[英]MaybeT's m in Type Signature
看看MaybeT
:
λ: import Monad.Trans
λ: import Monad.Trans.Maybe
λ: :t MaybeT
MaybeT :: m (Maybe a) -> MaybeT m a
在MaybeT
的簽名,可以m
是任何-kinded更高類型,即, * -> *
?
我正在努力學習Monad變形金剛,所以我很好奇為什么m
沒有Monad
的約束。
引用了解你一個Haskell :
我們已經遇到的參數化類型的另一個例子是來自
Data.Map
Map kv
。k
是映射中鍵的類型,v
是值的類型。 這是類型參數非常有用的一個很好的例子。 使參數化的映射使我們能夠從任何類型到任何其他類型的映射,只要鍵的類型是Ord
類型類的一部分。 如果我們定義了一個映射類型,我們可以在數據聲明中添加一個類型類約束:data (Ord k) => Map kv = ...
但是,在Haskell中, 永遠不會在數據聲明中添加類型類約束 。 為什么? 好吧,因為我們沒有受益很多,但我們最終寫了更多的類約束,即使我們不需要它們。 如果我們將或者不將
Ord k
約束放在Map kv
的數據聲明中,我們將不得不將約束放入假定可以對地圖中的鍵進行排序的函數中。 但是如果我們不將約束放在數據聲明中,我們就不必在函數的類型聲明中放入(Ord k) =>
,而不關心是否可以對鍵進行排序。 這樣一個函數的一個例子是toList
,toList
需要一個映射並將其轉換為一個關聯列表。 它的類型簽名是toList :: Map ka -> [(k, a)]
。 如果Map kv
在其數據聲明中有一個類型約束,則toList
的類型必須是toList :: Ord k => Map ka -> [(k, a)]
,即使該函數沒有做任何比較按訂單鍵。所以不要將類型約束放入數據聲明中,即使它似乎有意義,因為你必須將它們放入函數類型聲明中。
我希望能回答你的問題。 雖然MaybeT ma
的m
是不受約束的,但隱含的假設是m
是Monad
一個實例。 事實上,如果m
不是Monad
一個實例,那么你就無法對MaybeT ma
值做太多,因為大多數函數都要求m
是Monad
一個實例。
在
MaybeT
的簽名,可以m
是任何-kinded更高類型,即,* -> *
?
沒有:
> :k MaybeT
MaybeT :: (* -> *) -> * -> *
因此, MaybeT ma
類型中的m
必須與* -> *
類型完全相同,而不是任何其他類型。
例如,請注意以下類型錯誤:
> :k MaybeT (State Int)
MaybeT (State Int) :: * -> *
> :k MaybeT State
Expecting one more argument to ‘State’
The first argument of ‘MaybeT’ should have kind ‘* -> *’,
but ‘State’ has kind ‘* -> * -> *’
In a type in a GHCi command: MaybeT (State)
可以
m
是任何-kinded更高類型,即,* -> *
?
它可以是任何類型* -> *
。 除此之外,原則上沒有限制。
為什么
m
沒有Monad
的約束。
約束是通過使用MaybeT
的函數類型提供的,而不是通過MaybeT
構造函數。 除非涉及到GADT,否則向構造函數添加約束是沒有用的(我認為變換器為了簡單和符合標准而不使用GADT)。 有關約束和數據類型聲明的額外注釋,請參閱此問題及其答案 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.