Haskell 类型签名和 composite/multi-param 类型构造函数
Haskell type signature with composite/multi-param type constructors
我发现了这些类型的签名:
x :: a b -> Int
x f = 3
y :: a b c -> Int
y f = 3
z :: a b c d -> Int
z f = 3
> x [1] -- 3
> y (1, 2) -- 3
> z (1, 2, 3) -- 3
基本上:
- x 只接受包含 1 个或更多参数的类型构造函数的值。
- y 只接受包含 2 个或更多参数的类型构造函数的值。
- z 只接受包含 3 个或更多参数的类型构造函数的值。
它们是有效的,但我不确定它们的含义或用途。
它们似乎与类型构造函数上的多类型概念或多态性有关,但基于类型构造函数接受的许多参数强制执行不变量。
如果没有进一步的限制,这样的类型是无用的——你真的无法用它们做任何事情,期望将它们传递下去。但这实际上与签名 a -> Int
的情况相同:如果对 a
一无所知,您也无能为力!
但是,例如toInteger :: Integral a => a -> Integer
,向参数添加约束允许您做一些事情。例如,
import Data.Foldable
import Prelude hiding (foldr)
x' :: (Foldable a, Integral b) => a b -> Integer
x' = foldr ((+) . toInteger) 0
通常情况下,当你有一个 a b ... n o p q
形式的类型时,那么 a b ... p
至少是 Functor
class 的一个实例,通常还有 Applicative
和 Monad
;有时 Foldable
、Traversable
或 Comonad
;有时 a b ... o
将是 Arrow
...这些约束允许您对复合类型做很多事情,而无需知道您正在处理的特定类型构造函数。
在研究了@leftaroundabout 的答案并在 GHCI 中进行了实验之后,我开始理解复合类型。它们与应用类型的统一基于评估顺序和它们的类型变量的种类签名。评估顺序非常重要,因为 a b c ~ (((a) b) c)
而 a (b c)
是 (a ((b) c)
。这使得 a b c
匹配复合类型,其中 a
与类型构造函数 * -> * -> *
匹配,a b
与 * -> *
和 a b c
与 *
.
我在这个要点中用图表和 GHCI 代码对其进行了完整的解释 (https://gist.github.com/CMCDragonkai/2a1d3ecb67dcdabfc7e0)(堆栈溢出太长了)
我发现了这些类型的签名:
x :: a b -> Int
x f = 3
y :: a b c -> Int
y f = 3
z :: a b c d -> Int
z f = 3
> x [1] -- 3
> y (1, 2) -- 3
> z (1, 2, 3) -- 3
基本上:
- x 只接受包含 1 个或更多参数的类型构造函数的值。
- y 只接受包含 2 个或更多参数的类型构造函数的值。
- z 只接受包含 3 个或更多参数的类型构造函数的值。
它们是有效的,但我不确定它们的含义或用途。
它们似乎与类型构造函数上的多类型概念或多态性有关,但基于类型构造函数接受的许多参数强制执行不变量。
如果没有进一步的限制,这样的类型是无用的——你真的无法用它们做任何事情,期望将它们传递下去。但这实际上与签名 a -> Int
的情况相同:如果对 a
一无所知,您也无能为力!
但是,例如toInteger :: Integral a => a -> Integer
,向参数添加约束允许您做一些事情。例如,
import Data.Foldable
import Prelude hiding (foldr)
x' :: (Foldable a, Integral b) => a b -> Integer
x' = foldr ((+) . toInteger) 0
通常情况下,当你有一个 a b ... n o p q
形式的类型时,那么 a b ... p
至少是 Functor
class 的一个实例,通常还有 Applicative
和 Monad
;有时 Foldable
、Traversable
或 Comonad
;有时 a b ... o
将是 Arrow
...这些约束允许您对复合类型做很多事情,而无需知道您正在处理的特定类型构造函数。
在研究了@leftaroundabout 的答案并在 GHCI 中进行了实验之后,我开始理解复合类型。它们与应用类型的统一基于评估顺序和它们的类型变量的种类签名。评估顺序非常重要,因为 a b c ~ (((a) b) c)
而 a (b c)
是 (a ((b) c)
。这使得 a b c
匹配复合类型,其中 a
与类型构造函数 * -> * -> *
匹配,a b
与 * -> *
和 a b c
与 *
.
我在这个要点中用图表和 GHCI 代码对其进行了完整的解释 (https://gist.github.com/CMCDragonkai/2a1d3ecb67dcdabfc7e0)(堆栈溢出太长了)