Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 亲笔签名_Haskell_Types - Fatal编程技术网

Haskell 亲笔签名

Haskell 亲笔签名,haskell,types,Haskell,Types,我正在浏览Haskell的维基书籍 导游 我一直跟踪得很好,直到添加了一种签名,它概括了Cons构造函数的约束类型 data Safe data NotSafe data MarkedList :: * -> * -> * where Nil :: MarkedList t NotSafe Cons :: a -> MarkedList a b ->

我正在浏览Haskell的维基书籍

导游

我一直跟踪得很好,直到添加了一种签名,它概括了Cons构造函数的约束类型

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 :: * -> * -> *