因此,通過這一點,你當然聽說過討好或部分應用程序的:如果你有f :: a -> b -> c
和x :: a
,然後f x :: b -> c
。即,如果f
是雙參數函數,並且x
具有f
的第一個參數類型,則f x
是接受第二個參數並「完成」應用程序的函數。
那麼,在Haskell中,同樣的事情適用於類型構造函數,如State
。類型和類型構造函數有一個種類,這類似於值的類型。像Integer
這樣的非參數類型具有種類*
;像Maybe
這樣的單參數類型具有種類* -> *
; State
有種類* -> * -> *
。
然後,State state
是State
類型構造函數的部分應用程序,並且具有種類* -> *
。 Monad
是適用於種類* -> *
的類。因此,應用到我們的例子:
- 是被禁止的,因爲
Integer
有種*
。
instance Monad (Maybe) where ...
被允許,因爲Maybe
有種類* -> *
。
instance Monad (State) where ...
被禁止,因爲State
有種類* -> * -> *
。
instance Monad (State st) where ...
被允許,因爲State st
有種類* -> *
。
我們怎麼知道Monad
適用於種類* -> *
?我們可以從類聲明來推斷:
class Monad m where
return :: a -> m a
(>>=) :: m a -> (a -> m b) -> m b
-- ...
看m
是如何在這個類聲明中使用:作爲m a
和m b
,即一部分,因爲帶一個參數。因此,Haskell推斷m
是一種類型變量* -> *
。
比較此:
class Num a where
(+) :: a -> a -> a
(-) :: a -> a -> a
-- ...
這裏類型變量a
不被施加到其它類型的變量,因此它必須是樣*
。
嚴格地說,State
不是單子;它是一個兩位類型的構造函數,當部分應用於一種類型時,會給你一個monad。所以State state
是一個單子,因爲是State Integer
,State [a]
等人也常說鬆散和State
通話和類似事情的單子,雖然,但你應該明白這是一個參數化單子,它是有一個內部類型單子參數以及因此參數類型不同的許多變體。