簡體   English   中英

Monad Transformer 缺少參數(?)

[英]Monad Transformer missing parameter (?)

我有這種類型的別名:

type Board a = ReaderT String (StateT String IO) a

我知道StateT具有* -> (* -> *) -> * -> *類型,因此它應該獲得三個參數。 但在上面的示例中, StateT僅接收StringIO -Monad。 現在我想知道缺少的參數傳遞給StateT的位置。

IO如此,它應該得到一個參數但沒有得到任何參數。

如果您查看ReaderT的定義,您會看到它的第二個參數本身應用於它的最后一個參數:

newtype ReaderT r m a = ReaderT { runReaderT :: r -> m a }
                                                     ^^^
                                                  right here

這意味着它的第二個參數m必須具有種類m:: * -> * 如果您只向StateT應用兩個而不是三個參數,這正是您得到的結果:

StateT :: * -> (* -> *) -> * -> *
StateT x y :: * -> *
(where x :: * and y :: * -> *)

在您的類型Board中替換ReaderT的定義時,您將得到:

(1) type Board a = ReaderT String (StateT String IO) a

-- Substituting ReaderT definition (pseudocode)
(2) type Board a = { runReaderT :: String -> StateT String IO a }
                                             ^^^^^^^^^^^^^^^^^^
                                Look, StateT has all its three parameters!

你正確地觀察到

StateT具有類型* -> (* -> *) -> * -> *

ReaderT也是如此。

所以它需要 3 個你所說的“參數”。 第一個是*類型的String ,第三個是*類型的a 而第二個必須是* -> *

這在您的示例中由StateT String IO 因此,盡管在某種意義上存在StateT的“缺失參數”,但這需要“缺失”才能獲得某種東西* -> * - 如果您嘗試了類似type Board a = ReaderT String (StateT String IO Int) a ,這將失敗並出現“種類錯誤”,正是因為ReaderT的第二個類型參數需要是種類* -> * ,而不是種類* StateT String IO Int會擁有。

這同樣適用於為什么IO使用而不是IO a形式的東西。 StateT String (IO Int)不起作用,因為StateT需要應用於某種類型* -> *作為其第二類型參數 - IO具有這種類型,但IO Int (或任何形式的IO a )沒有。

退一步說,像ReaderTStateT這樣的 monad 轉換器會轉換另一個 monad,並且 monad 必須始終是* -> *類型。 IO是一個 monad, StateT String IO 但是IO IntStateT String IO Int不是單子——並不是因為不符合單子法或類似的東西,而是為了更基本的意義,它們是錯誤的類型。 (它們是“具體類型”——具有值的類型——而不是將另一種類型作為參數的“類型構造函數”。)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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