IdentityT 变压器的用途是什么?

发布于 2025-01-02 05:09:25 字数 348 浏览 1 评论 0原文

在查看 Transformers 包时,我发现这个 monad 转换器名为 身份T

虽然我了解 Identity monad 的使用方式(例如 StateT Identity 只是 StateT Identity 的别名)以及 monad 转换器的一般工作原理,但我不知道它与身份T

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

While looking through the transformers package, I found this monad transformer called IdentityT.

Although I understand how the Identity monad is used (e.g. State is just an alias for StateT Identity) and how monad transformers work in general, I have no idea how that relates to IdentityT.

Since it's not in the MTL, I'm guessing it was added in there just for completeness and has no practical use. Is that correct?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

红焚 2025-01-09 05:09:25

那么链接的文档确实说

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

尽管我不知道有任何情况确实如此。理论上,如果你有一个类似 foo :: (MonadTrans t, Monad m) => 的函数tma-> b 对于一些有用的 b,那么您可能希望能够将其“简化”为本质上 ma ->; b 通过使用t = IdentityT

IdentityT 之于 MonadTrans 就像 Identity 之于 Monad 一样。它是“直通”转换器,因为 Identity 是“直通”单子。只需查看来源即可;这很简单。 IdentityT SomeMonad a 的行为应该与 SomeMonad a 相同,唯一的区别是存在额外的新类型(当然,它在编译时被删除)

Well the linked documentation does say

This is useful for functions parameterized by a monad transformer.

Though I'm not aware of any situations where this is actually the case. Theoretically if you have a function like foo :: (MonadTrans t, Monad m) => t m a -> b for some useful b, then you might want to be able to "dumb it down" to essentially m a -> b by using t = IdentityT.

But IdentityT is to MonadTrans what Identity is to Monad. It is the "pass-through" transformer, as Identity is the "pass-through" monad. Just check out the source; it's rather simple. IdentityT SomeMonad a should behave identically to SomeMonad a, the only difference being the presence of an extra newtype (which, of course, is removed at compile time)

心欲静而疯不止 2025-01-09 05:09:25

这里有一个建议的用法(大概是 IdentityT 的起源:
http://www.haskell.org/pipermail/libraries/2007-June /007563.html

主要用途似乎是在源代码级别提供灵活性,例如,有人可以将源代码编辑为 xmonad 并替换自己的 UserT 而无需编辑代码太多。

我试图看看这如何适用于一个库 - 你可以使用它来提供一个占位符,用于在堆栈中间插入一个单子,但我不确定是否有一个很好的例子。这是我设计的例子:

{-# 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]

There's a proposed usage here (presumably the origin of IdentityT:
http://www.haskell.org/pipermail/libraries/2007-June/007563.html

The main use seems to be to allow flexibility at the source code level, e.g. someone can edit the source to xmonad and substitute their own UserT without editing too much code.

I tried to see how that could work for a library - you can use it to provide a placeholder for inserting a monad in the middle of a stack, I'm not sure of a great case for that though. Here's my contrived example:

{-# 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]
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文