我似乎找不到真正解釋型別類定義中| m -> s含義的書籍:MonadState
class Monad m => MonadState s m | m -> s where
{- other stuff here -}
我正在閱讀的這本書解釋了
s型別變數表示一種狀態。它m由部件指定的 monad 唯一確定| m -> s。
但我不明白這到底是什么意思。
我理解的程度是它m必須是帶有Monad實體的某種型別,并且m將具有它包含的值。這是否意味著所提供的 monads會出現m s在型別運算式中——即類似的東西return :: Monad m => s -> m s?
uj5u.com熱心網友回復:
它被稱為功能依賴。它所做的只是對允許為該類定義的實體設定一些限制。
這意味著箭頭左側的變數(m在這種情況下)必須確定箭頭右側的變數(s在這種情況下)。1您不能定義多個實體,這樣您就無法s在選擇m.
例如,這是非法的:
data MyStateMonad = ...
instance MonadState MyStateMonad Int
instance MonadState MyStateMonad Bool
對于上述情況,一旦m確定是,MyStateMonad我們不能立即推斷出s必須是什么;Int和都有實體Bool。這在普通的多引數型別類中會非常好,但是函式依賴m -> s禁止它。
它實作的主要目標(作者為什么要強加該限制)是 GHC 知道該限制,并且可以在型別推斷期間使用它。MonadState有一個函式接受一個帶有約束的一元值(m a對于 some )是很常見的,但只在內部與狀態型別a互動。s如果 GHC 必須考慮每個 可能有多個MonadState實體的可能性m,并且具有不同s的 ,那么這樣的代碼通常會模棱兩可;程式員必須添加更多型別注釋才能編譯它。
但這通常不是一種可能的情況,因為很多MonadState實體最終都建立在StateT2上,看起來像這樣:
newtype StateT s m a = StateT { runStateT :: s -> m (a,s) }
這已經有一個狀態的型別引數!我們幾乎永遠不會想要M一個StateT Int _ _內部有一個MonadState M Bool實體的型別。我們已經確定狀態應該是我們使用Int的引數之一。StateT它真正有意義的唯一方法是,如果里面M有a和; 從理論上講,我們可能需要兩個實體來控制使用哪個型別。3StateT Int _ _StateT Bool _ _MonadStateM
但相反,作者決定使用函式依賴來犧牲撰寫此類東西的能力,而是更好地支持只有一種狀態型別對任何給定狀態單子有意義的用例。現在,一旦您的型別簽名確定了您正在使用的 monad,編譯器就可以使用它來識別MonadState實體,然后告訴它s必須是什么。這有效地將型別資訊添加到每次使用的MonadState方法中,而無需程式員撰寫額外的型別注釋。
1或者反過來說,箭頭右邊的依賴于左邊的——就像函式的結果依賴于它的引數一樣(因此稱為函式依賴)。
2 “最終建立在”我并不一定意味著該MonadState實體實際上是針對某些組合StateT引數的。只是實體的第一個引數中的某處通常是 a StateT,MonadState實體將“狀態”行為提升到頂部。
3我實際上不確定你是否能通過單子定律。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/506256.html
標籤:哈斯克尔
