Haskell 什么是实物签名约束

Haskell 什么是实物签名约束,haskell,type-kinds,constraint-kinds,Haskell,Type Kinds,Constraint Kinds,如果我检查的种类,可能我会得到: λ> :k Maybe Maybe :: * -> * λ> :k Monad Monad :: (* -> *) -> Constraint 现在,如果我检查Monad的类型,我会得到: λ> :k Maybe Maybe :: * -> * λ> :k Monad Monad :: (* -> *) -> Constraint 什么是约束,为什么需要约束?为什么不仅仅是这个*->*?与可能不

如果我检查
种类
,可能
我会得到:

λ> :k Maybe
Maybe :: * -> *
λ> :k Monad
Monad :: (* -> *) -> Constraint
现在,如果我检查
Monad
的类型,我会得到:

λ> :k Maybe
Maybe :: * -> *
λ> :k Monad
Monad :: (* -> *) -> Constraint

什么是约束,为什么需要约束?为什么不仅仅是这个
*->*

可能不同,
Monad
不是一种类型;这是一个typeclass。

其他类型类也是如此:

Num :: * -> Constraint
Functor :: (* -> *) -> Constraint
Bifunctor :: (* -> * -> *) -> Constraint
其中,
*
表示具体类型(如
Bool
Int
),
->
表示更高级的类型(如
可能
),而
约束
表示类型约束的概念。这就是为什么:


正如我们所知,我们不能做出这样的签名:

return :: a -> Monad a -- This is nonsense!
因为
Monad
应该用作约束,所以说“这必须是一个Monad才能工作”:

return :: (Monad m) => a -> m a
我们这样做是因为我们知道
return
不能在任何旧类型
m
上工作,所以我们在
Monad
的名称下为不同类型定义
return
的行为。换句话说,没有一种东西可以称为单子,只有一种行为可以称为单子

出于这个原因,我们创建了这个类型约束,说我们必须预先定义一些东西作为Monad来使用这个函数。这就是为什么
Monad
的类型是
(*->*)->约束
——它本身不是一种类型


可能是
Monad
的一个实例。这意味着在某个地方,有人写道:

instance Monad Maybe where
  (>>=) = ... -- etc

…并定义了
可能
作为单子的行为方式。这就是为什么我们可以对具有前缀约束的函数或类型使用
Maybe
Monad m=>…
。这基本上就是定义由
Monad
应用的约束的地方。约束是一种约束,例如
Show Int
Monad Maybe
,和
Monoid[a]
。大致上,它是类型注释中
=>
左侧可能出现的所有内容

从现在起

Show Int :: Constraint
Int
是一种类型,即

Int :: *
我们可以为
Show
指定一个函数类型,如下所示

Show :: * -> Constraint
             ^-- the result kind
        ^-- the kind of Int
在您的例子中,
Monad
恰好接受像
Maybe
这样的参数,所以

Maybe Int :: *
Maybe :: * -> *
Monad :: (* -> *) -> Constraint
                     ^-- the result kind
         ^-- the kind of Maybe