所以到目前为止,您肯定已经听说过柯里化或部分应用:如果您有f :: a -> b -> c
and x :: a
,那么f x :: b -> c
. 即,Iff
是一个双参数函数并且x
具有 的f
第一个参数的类型,那么f x
是一个接受第二个参数并“完成”应用程序的函数。
好吧,在 Haskell 中,同样的事情也适用于类型构造函数,例如State
. 类型和类型构造函数具有kind,类似于值如何具有类型。Integer
像有 kind的非参数类型*
;像Maybe
有 kind的单参数类型* -> *
;State
有种* -> * -> *
。
然后,State state
是State
类型构造函数的部分应用,并且有 kind * -> *
。 Monad
是适用于 kind 的类* -> *
。因此,应用于我们的示例:
instance Monad (Integer) where ...
被禁止是因为Integer
有善良*
。
instance Monad (Maybe) where ...
被允许是因为Maybe
有种* -> *
。
instance Monad (State) where ...
被禁止是因为State
有善良* -> * -> *
。
instance Monad (State st) where ...
被允许是因为State st
有种* -> *
。
我们怎么知道它Monad
适用于 kind 类型* -> *
?我们可以从类声明中推断出来:
class Monad m where
return :: a -> m a
(>>=) :: m a -> (a -> m b) -> m b
-- ...
看看在m
这个类声明中是如何使用的:作为 and 的一部分m a
,m b
即作为一个参数。因此,Haskell 推断这m
是 kind 的类型变量* -> *
。
与此相比:
class Num a where
(+) :: a -> a -> a
(-) :: a -> a -> a
-- ...
这里类型变量a
不应用于其他类型变量——因此它必须是 kind *
。
所以严格来说,State
不是monad;它是一个两位类型的构造函数,当部分应用于仅一种类型时,它会为您提供一个 monad。monad 也是如此State state
,就像State Integer
,State [a]
等一样。尽管人们确实经常谈论和谈论State
类似 monad 的东西,但是你应该理解它是一个参数化的 monad——它是一个具有内部类型参数的 monad,因此有许多变体该参数的类型不同。