如果我检查kind
Maybe
我得到了这个:
λ> :k Maybe
Maybe :: * -> *
现在,如果我检查Monad
我得到的那种:
λ> :k Monad
Monad :: (* -> *) -> Constraint
那里是Constraint
是什么以及为什么需要它?为什么不只是这个* -> *
?
答案 0 :(得分:11)
与Maybe
不同,Monad
不是类型;它是类型类。
其他类型类也是如此:
Num :: * -> Constraint
Functor :: (* -> *) -> Constraint
Bifunctor :: (* -> * -> *) -> Constraint
*
代表具体类型(例如Bool
或Int
),->
代表更高级别的类型(例如Maybe
)和{ {1}}表示类型约束的概念。这就是原因:
据我们所知,我们无法签名:
Constraint
因为return :: a -> Monad a -- This is nonsense!
应该用作约束,所以说,“这必须是一个单独的工作':
Monad
我们这样做是因为我们知道return :: (Monad m) => a -> m a
无法处理任何旧类型return
,因此我们会在m
下为不同类型定义return
的行为1}}。换句话说,没有任何东西可以被称为Monad,但只有可以被称为Monadic的行为。
出于这个原因,我们已经创建了这个类型约束,说我们必须预先定义一些东西作为Monad来使用这个函数。这就是为什么Monad
是Monad
- 它本身不是一种类型!
(* -> *) -> Constraint
是Maybe
的一个实例。这意味着在某个地方,有人写道:
Monad
...并定义instance Monad Maybe where
(>>=) = ... -- etc
应如何表现为Monad。这就是我们可以将Maybe
用于具有前缀约束Maybe
的函数或类型的原因。这基本上是定义Monad m => ...
所应用的约束的地方。
答案 1 :(得分:8)
Constraint
是一种例如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