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
。这意味着你将另一个monad层叠在“IO
之上”。这让你有一般操作
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
例如,最简单的很是MonadTrans
IdT
。
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
这只是彼此的反转,在这种情况下。一般来说,行为可能更复杂。
对'm a'到'IO a',看看'MonadIO'中的'liftIO'。更一般地说,从'MonadTrans'提升''。否则,也许你会对'mmorph'包感兴趣。 – thoferon
你可能意识到了这一点,但只是说:'\ X - >回x'简直是'return',并通过法律的单子'V >> = return'必须是'v'再次,始终。所以目前你只有'funcX = abc'。 – leftaroundabout
这是不可能通过设计。你不能从一个值解开IO。它永远像钻石一样。或许,如果你告诉我们你想解决什么问题,我们就可以帮你。 –