Haskell 亲笔签名
我正在浏览Haskell的维基书籍 导游 我一直跟踪得很好,直到添加了一种签名,它概括了Cons构造函数的约束类型Haskell 亲笔签名,haskell,types,Haskell,Types,我正在浏览Haskell的维基书籍 导游 我一直跟踪得很好,直到添加了一种签名,它概括了Cons构造函数的约束类型 data Safe data NotSafe data MarkedList :: * -> * -> * where Nil :: MarkedList t NotSafe Cons :: a -> MarkedList a b ->
data Safe
data NotSafe
data MarkedList :: * -> * -> * where
Nil :: MarkedList t NotSafe
Cons :: a -> MarkedList a b -> MarkedList a c
safeHead :: MarkedList a Safe -> a
safeHead (Cons x _) = x
silly 0 = Nil
silly 1 = Cons () Nil
silly n = Cons () $ silly (n-1)
有了Kind签名,我可以使用Cons构造函数来构造和模式匹配安全和不安全的标记列表。虽然我知道发生了什么,但不幸的是,我很难建立起任何直觉来理解这种签名是如何允许的。为什么我需要那种签名?这种签名在做什么 与类型签名用于值的方式相同,种类签名用于类型
f :: Int -> Int -> Bool
f x y = x < y
类型D
采用两种参数类型并生成一种结果类型(它是*->*->*->*
)。例如,D Int String
是一种类型(其具有种类*
)。部分应用程序D Int
具有种类*->*
,就像部分应用程序f 15
具有类型Int->Bool
一样
因此,我们可以将上述内容改写为:
data D :: * -> * -> * where
D :: a -> b -> D a b
在GHCi中,可以查询类型和种类:
> :type f
f :: Int -> Int -> Bool
> :kind D
D :: * -> * -> *
我仍然感到困惑,因为在GHC 7.4.1中,
标记的列表a b中…
似乎也适用。我不确定kind签名提供了什么。这看起来像是对我说同样事情的另一种方式。是的,但是kind签名需要一种语言pragma,而后者不需要。为什么,如果两种方法都一样?种类签名提供了什么额外的功能?在其他情况下,您可能需要指定替代种类。例如,数据X a=X
。这里,X
具有种类*->*
,其参数必须为空。您可以使用数据X(a::*->*)=X
为其参数指定一元种类,因此X
将具有种类(*->*)->*
,因此您可以例如在函子或单子或非空的对象上参数化X
。我认为在你所说的例子中没有必要。@外现实:(Re:“除了Dietrich Epp所说的以外,什么样的签名可以提供?”一个人可以考虑< <代码> MaqDLIST B,其中…语法有点误导,因为它看起来像名字<代码> A<代码>和<代码> B/COD>被绑定在正文中使用。(在where
之后),实际上,它们没有任何效果(每个构造函数绑定自己的名称)。编写标记列表::*->*->*->*
可以避免这种情况。不过,这只是一个品味问题。
> :type f
f :: Int -> Int -> Bool
> :kind D
D :: * -> * -> *