12

在查看 transformers 包时,我发现了这个名为IdentityT的 monad 转换器。

尽管我了解 Identity monad 的使用方式(例如State只是 的别名StateT Identity)以及 monad 转换器的一般工作方式,但我不知道这与IdentityT.

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

4

2 回答 2

6

那么链接的文档确实说

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

尽管我不知道实际上是这种情况的任何情况。从理论上讲,如果您有foo :: (MonadTrans t, Monad m) => t m a -> b一些有用的功能b,那么您可能希望能够m a -> b通过使用t = IdentityT.

但是IdentityTMonadTrans什么Identity是什么Monad。它是“通过”转换器,Identity“通过”单子也是如此。只需查看来源;这很简单。IdentityT SomeMonad a行为应该与 相同SomeMonad a,唯一的区别是存在额外的新类型(当然,在编译时将其删除)

于 2012-02-03T08:21:02.910 回答
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]
于 2012-02-03T03:24:50.770 回答