在查看 transformers 包时,我发现了这个名为IdentityT的 monad 转换器。
尽管我了解 Identity monad 的使用方式(例如State只是 的别名StateT Identity)以及 monad 转换器的一般工作方式,但我不知道这与IdentityT.
由于它不在 MTL 中,我猜它只是为了完整性而添加在那里并且没有实际用途。那是对的吗?
在查看 transformers 包时,我发现了这个名为IdentityT的 monad 转换器。
尽管我了解 Identity monad 的使用方式(例如State只是 的别名StateT Identity)以及 monad 转换器的一般工作方式,但我不知道这与IdentityT.
由于它不在 MTL 中,我猜它只是为了完整性而添加在那里并且没有实际用途。那是对的吗?
那么链接的文档确实说
这对于由 monad 转换器参数化的函数很有用。
尽管我不知道实际上是这种情况的任何情况。从理论上讲,如果您有foo :: (MonadTrans t, Monad m) => t m a -> b一些有用的功能b,那么您可能希望能够m a -> b通过使用t = IdentityT.
但是IdentityT是MonadTrans什么Identity是什么Monad。它是“通过”转换器,Identity“通过”单子也是如此。只需查看来源;这很简单。IdentityT SomeMonad a行为应该与 相同SomeMonad a,唯一的区别是存在额外的新类型(当然,在编译时将其删除)
这里有一个建议的用法(大概是 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]