2012-02-03 58 views
11

在翻閱變壓器包的同時,我發現這個稱爲IdentityT的monad變壓器。IdentityT變壓器的用途是什麼?

雖然我理解的身份單子是如何使用的(如State僅僅是StateT Identity的別名),以及如何單子變壓器工作在一般情況下,我不知道如何,涉及到IdentityT

由於它不在MTL中,我猜測它是爲了完整性而添加的,沒有實際用途。那是對的嗎?

回答

6

嘛鏈接文檔中則說

這是由一個單子轉換參數的功能非常有用。

雖然我不知道任何情況下,這實際上是這種情況。理論上,如果你有一個功能foo :: (MonadTrans t, Monad m) => t m a -> b對於一些有用的b,那麼你可能希望能夠通過使用t = IdentityT來「虛弱」到m a -> b

但是IdentityT是到MonadTrans什麼Identity是到Monad。這是「直通」變壓器,因爲Identity是「直通」monad。只需查看源代碼;這很簡單。 IdentityT SomeMonad a的行爲應該與SomeMonad a的行爲相同,唯一的區別是存在額外的新類型(當然,這在編譯時會被刪除)

2

這裏有一個建議使用(大概IdentityT的由來: http://www.haskell.org/pipermail/libraries/2007-June/007563.html

主要用途似乎是允許在源代碼級的靈活性,例如,有人可以編輯源xmonad並替換自己UserT沒有編輯太多的代碼

我試圖看看如何可以爲圖書館工作 - 你可以用它來提供一個佔位符插入monad在堆棧的中間,我不知道一個偉大的案例這是我設計的例子:

{-# LANGUAGE GeneralizedNewtypeDeriving #-} 

module Main where 

import Control.Monad.State 
import Control.Monad.List 
import Control.Monad.Reader 

type X m a = StateT Int (m IO) a 

something :: (Monad (m IO), MonadIO (m IO)) => (m IO) Int -> X m Int 
something a = do 
     x <- lift a 
     put (x + 1) 

     liftIO $ print x 
     return x 



listSomething = something $ ListT (mapM return [1,2,3,4]) 
plainSomething = return 5 :: IdentityT IO Int 

main = do 
    x <- runListT (execStateT listSomething 3) 
    print x 

    y <- runIdentityT (execStateT plainSomething 3) 
    print y 

runIdentity $ mapM (return . (+1)) [1..100]