簡體   English   中英

也許是簽名類型

[英]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) => ,而不關心是否可以對鍵進行排序。 這樣一個函數的一個例子是toListtoList需要一個映射並將其轉換為一個關聯列表。 它的類型簽名是toList :: Map ka -> [(k, a)] 如果Map kv在其數據聲明中有一個類型約束,則toList的類型必須是toList :: Ord k => Map ka -> [(k, a)] ,即使該函數沒有做任何比較按訂單鍵。

所以不要將類型約束放入數據聲明中,即使它似乎有意義,因為你必須將它們放入函數類型聲明中。

我希望能回答你的問題。 雖然MaybeT mam是不受約束的,但隱含的假設是mMonad一個實例。 事實上,如果m不是Monad一個實例,那么你就無法對MaybeT ma值做太多,因為大多數函數都要求mMonad一個實例。

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM