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