gpt4 book ai didi

haskell - mapMonadTrans::MonadTrans xT => (m a -> n b) -> xT m a -> xT n b

转载 作者:行者123 更新时间:2023-12-04 16:36:22 26 4
gpt4 key购买 nike

问题是这个。我有:

f :: MonadIO m => ReaderT FooBar m Answer;
f = (liftIO getArgs) >>= ...

我需要使用修改后的参数运行它。但是,由于 m 未知,我不能简单地使用
mapReaderT (withArgs args) :: ReaderT r IO b -> ReaderT r IO b

因为我需要以某种方式将所有 m 的 (withArgs args) 转换为 m。

我发现的一种可能性是定义我自己的 withArgs,因此:
import System.Environment (setArgs, freeArgv);
withArgv new_args act = do {
pName <- liftIO System.Environment.getProgName;
existing_args <- liftIO System.Environment.getArgs;
bracket (liftIO $ setArgs new_args)
(\argv -> do {
_ <- liftIO $ setArgs (pName:existing_args);
liftIO $ freeArgv argv;
})
(const act);
};

withArgs xs act = do {
p <- liftIO System.Environment.getProgName;
withArgv (p:xs) act;
};

然而,这是杂乱无章的,并且特定于一个函数——我需要重写每个 withX :: X -> IO a -> IO a ,例如控制.异常.句柄

如果有的话,有什么更好的方法来做到这一点?

编辑:在句柄的情况下,我找到了 Control.Monad.CatchIO。在另一种情况下,我使用了另一个更简短的 kludge(不值得发布)来避免上面的 kludge。仍在寻求更好的解决方案!

最佳答案

您正在寻找的部分内容是将 monad 同态提升为 monad 转换器。

class MonadHoist t where
hoist :: (Monad m, Monad n) => (forall a. m a -> n a) -> t m a -> t n a

t :: Monad m => t Identity a -> t m a
t = hoist (return . runIdentity)

也就是说,给定一个 monad 同态 f来自 mn ,你可以从 t m 得到一个 monad 同态至 t n使用葫芦。

monad 同态比上面执行的类型稍强,即它负责保留 monad 定律。
f . return = return
f . fmap g = fmap g . f
f . join = join . f . fmap f
= join . fmap f . f -- by the second law
= (>>= f) . f -- >>= in terms of join

注意我在 hoist 类型中隐藏的量词, MonadHoist事实证明,几乎所有情况都需要这种灵活性! ( Reader 恰好是它没有的一种情况。尝试在没有它的情况下编写 MaybeT。)

Monad 转换器通常可以实例化此类。例如:
instance MonadHoist (StateT s) where
hoist f (StateT m) = StateT (f . m)

instance MonadHoist (ReaderT e) where
hoist f (ReaderT m) = ReaderT (f . m)

instance MonadHoist MaybeT where
hoist f (MaybeT m) = MaybeT (f m)

我们目前没有在 transformers 中提供它或 mtl包,因为它需要一个 Rank2Type ,但实现起来非常简单。

如果有足够的需求,我很乐意打包在 monad-extras包裹。

现在,我说部分,因为虽然这回答了您帖子主题中的类型给出的问题,但它并没有解决与您的问题相关的大部分文本所反射(reflect)的需求!

为此,您可能想听从 luqui 的建议。 =)

关于haskell - mapMonadTrans::MonadTrans xT => (m a -> n b) -> xT m a -> xT n b,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6601208/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com