- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试创建一个仅允许特定 IO 函数的 monad。这意味着这个假设的 monad 不能是 MonadIO
并且不能允许调用 liftIO
。
这是我到目前为止所拥有的,但我一直使用 AppM
的 Monad
实例:
data AppM a = AppM {unwrapAppM :: ReaderT Env (LoggingT IO) a}
instance Functor AppM where
fmap fn appm = AppM $ fmap fn (unwrapAppM appm)
instance Applicative AppM where
pure a = AppM $ pure a
最佳答案
如果您只是想隐藏 AppM
的 MonadIO
特性
我会继续输入
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
并将data
声明更改为
newtype App a = App {runApp :: ReaderT Env (LoggingT IO) a}
deriving (Functor, Applicative, Monad, MonadReader Env,
, MonadLoggerIO }
因此,如果您需要像 liftIO
这样的操作,您的 App
就不是 MonadIO
,您可以在库中提供这些操作,例如
putStrLn :: String -> App ()
putStrLn = fmap App . liftIO Prelude.putStrLn
注意:liftIO
用于 ReaderT Env (LoggingT IO) ()
,然后将其包装到 App
中,并且您不会公开完整的 IO 功能。
关于如何实现Functor
、Applicative
和Monad
的问题,它只是包装/展开的任务:
instance Functor App where
fmap f = App . fmap f . runApp
instance Applicative App where
pure = App . pure
mf <*> mx = App (runApp mf <*> runApp mx)
instance Monad App where
mx >>= f = App $ (runApp mx) >>= (runApp . f)
最后一行是唯一棘手的 - 正如
>>= :: ReaderT Env (LoggingT IO) a -> (a -> ReaderT Env (LoggingT IO) b) -> ReaderT Env (LoggingT IO) b
但是 mx::App a
和 f::a -> App b
所以我们需要
runApp :: App a -> ReaderT Env (LoggingT IO) a
解包 f
的结果类型以在解包设置中工作 - 这在写下来时似乎非常明显,但在此之前可能会引起一些头痛。
我发现有人从 monad reader Ed Z. Yang - Three Monads (Logic, Prompt, Failure) 链接了我很长一段时间(但在同一个星系)的论文。
关于haskell - 如何创建一个允许 IO 但不是 MonadIO 的 monad?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45266054/
两者有什么区别: recompile :: MonadIO m => Bool -> m Bool recompile :: Bool -> IO Bool 最佳答案 类型 forall m. Mon
在reactive-banana中,我尝试使用hArduino package中的Arduino的一些操作来运行reactimate::Event (IO ()) -> Moment () ,Mona
我一直在使用 HMatrix 进行线性代数,它是 linearSolve函数具有简单(尽管简洁)类型: linearSolve :: Field t => Matrix t -> Matrix t -
我的程序中有一个 MonadIO 实例,我想从该 MonadIO 中抛出/捕获异常(来自基础包中的 Control.Exception 模块)。 快速的 Google 搜索返回了大量讨论(可追溯到 2
我在进行简单的蒙特卡洛模拟时遇到了这个问题。我使用 MonadIO、MonadState 和 MonadRandom 来简化程序状态的维护。我遇到了 Count not deduce 错误,但是当我删
我正在尝试创建一个仅允许特定 IO 函数的 monad。这意味着这个假设的 monad 不能是 MonadIO 并且不能允许调用 liftIO。 这是我到目前为止所拥有的,但我一直使用 AppM 的
在下面的代码中,我尝试将 2 个生产者合并为 1 个。所有生产者都具有相同的类型。它们将由在单独线程中运行的 2 个输入Producer 中的每一个组合而成,并由将值放入 unagi chan 的 C
首先声明一下,由于我对 Haskell 的了解不够深入,我可能完全误解了threepenny-gui 的工作方式,所以请对我的断言持保留态度。 :-) 在我看来,一些组合器不是纯粹的,例如 stepp
我一直在努力理解 mtl通过将其与 persistent 结合使用来构建项目. 该项目的一个模块具有使用 insertMany_ 的功能。 service :: (MonadReader Appl
所以在变形金刚中我明白了, class (Monad m) => MonadIO m where -- | Lift a computation from the 'IO' monad.
我是一名优秀的程序员,十分优秀!