身份变换器的目的是什么?

时间:2012-02-03 02:09:28

标签: haskell monads monad-transformers

在查看变形金刚包时,我发现这个名为IdentityT的monad变换器。

虽然我理解如何使用Identity monad(例如State只是StateT Identity的别名)以及monad变换器如何工作,我不知道它与{{1}的关系}。

由于它不在MTL中,我猜它是为了完整而添加在那里并没有实际用途。这是对的吗?

2 个答案:

答案 0 :(得分:6)

链接文档确实说

  

这对由monad变换器参数化的函数很有用。

虽然我并不知道任何情况确实如此。从理论上讲,如果你有一个像foo :: (MonadTrans t, Monad m) => t m a -> b这样的函数用于某些有用的b,那么你可能希望能够使它变得愚蠢。使用m a -> b来实质上t = IdentityT

IdentityTMonadTrans IdentityMonad的内容。这是"传递"变压器,Identity是"传递"单子。看看来源;它很简单。 IdentityT SomeMonad a应该与SomeMonad a的行为相同,唯一的区别是存在一个额外的新类型(当然,在编译时删除)

答案 1 :(得分: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]