【问题标题】:Haskell Convert from IO a to m aHaskell 从 IO a 转换为 m a
【发布时间】:2013-10-17 11:44:59
【问题描述】:

我想将一元值转换为其他 Monad 类的一元值。

假设我有一个实例声明:

    instance ClassM TypeT where
        funcX = abc >>= \x -> return (x)

ClassM : 是一个自己的 monad 定义的类
TypeT : 是一个自己定义的类型/数据,带有一个 monad 实例实现
abc : 属于 IO a 类型

如何转换 abc::IO a 的一元值
到 classM m => m a
的一元值 又名 m1 a -> m2 a(其中 m1 不是 m2)(例如:IO 5 -> Just 5)

我的 funcX 实现显然不正确。如果可能,正确的实现应该是什么?

感谢您的时间和帮助。

【问题讨论】:

  • 对于m aIO a,请查看MonadIO 中的liftIO。更一般地说,lift 来自 MonadTrans。否则,也许你会对 mmorph 包感兴趣。
  • 您可能已经意识到这一点,但只是说:\x -> return x 只是 return,并且根据单子法则,v >>= return 必须再次成为 v,始终如此。所以目前你只有funcX = abc
  • 设计不可能。您不能将 IO 从值中解开。它是永恒的,就像钻石一样。也许如果您告诉我们您要解决的问题,我们将能够为您提供帮助。

标签: haskell monads


【解决方案1】:

Monad 这个类代表了所有的单子——它是一个形容词而不是一个名词。如果您想将特定的 monad 转换为在所有 monad 中通用的值,则该类型看起来像其中之一

Monad m => IO a       -> m a
Monad m => Maybe a    -> m a
Monad m => [a]        -> m a
Monad m => Either e a -> m a

虽然one type of very special monads 有这个属性,但通常是不可能的。

您可能会做的另一件事是使用Monad 转换器,IO 在底部。这意味着您在“IO”之上添加了另一个 monad。这让您可以进行一般操作

lift :: MonadTrans t => m a -> t m a     -- notice that t takes two parameters
lift :: IO a -> MyTransformer IO a       -- specializing the generic function

还有,根据MyTransformer是什么,具体操作

runMyTransformer :: MyTransformer m a -> m a
runMyTransformer :: MyTransformer IO a -> IO a   -- specialized

例如,最简单的MonadTransIdT

newtype IdT m a = IdT { runIdT :: m a } deriving Functor

instance Monad m => Monad (IdT m) where
  return a = IdT (return a)
  IdT ma >>= f = IdT (ma >>= runIdT . f) 

instance MonadTrans IdT where
  lift ma = IdT ma

给我们操作

lift   :: IO a -> IdT IO a
runIdT :: IdT IO a -> IO a

在这种情况下,它们只是彼此的倒数。一般来说,行为可能要复杂得多。

【讨论】:

    【解决方案2】:

    Monad“类”它不是来自对象的“类”。

    您在询问Comonads->Monad 转换:Comonad package

    convert :: (Comonad w, Monad m) => w a -> m a
    convert = return . extract
    

    在任何情况下,你都不能从 IO 获得 comonad

    您可以使用unsafePerormIO 来使用一些hackery

    【讨论】:

    • unsafePerformIO:你可以,但在大多数情况下你不应该。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-23
    • 1970-01-01
    • 1970-01-01
    • 2020-06-11
    • 1970-01-01
    • 2021-10-15
    相关资源
    最近更新 更多