有人可以提供一个超级简单(几行)monad变换器示例,这是非平凡的(即不使用Identity monad - 我理解).
例如,有人会如何创建一个执行IO并可以处理失败的monad(可能)?
什么是最简单的例子来证明这一点?
我已经浏览了一些monad变换器教程,他们似乎都使用State Monad或Parsers或者复杂的东西(对于newbee).我想看到一些比这简单的东西.我认为IO +也许会很简单,但我自己并不知道如何做到这一点.
我怎么能使用IO + Maybe monad堆栈?最重要的是什么?什么会在底部?为什么?
在什么样的用例中,人们想要使用IO + Maybe monad还是Maybe + IO monad?创造这样一个复合单子会有意义吗?如果是,何时以及为什么?
我正在编写一个具有非常复杂的循环的脚本:
main = do
inFH <- openFile "..." ReadMode
outFH <- openFile "..." WriteMode
forM myList $ \ item ->
...
if ...
then ...
else do
...
case ... of
Nothing -> ...
Just x -> do
...
...
Run Code Online (Sandbox Code Playgroud)
代码很快就会飞到右边,所以我想把它分成几块,使用例如where子句.问题是,许多这些...包含读/写语句到两个把手inFH和outFH,使用where的语句将呈现这两个名字断章取义.我每次使用where语句时都必须发送这两个变量.
有没有更好的方法来解决这个问题?
试图了解用于处理内部可能出现的故障的模式IO。如果它只是case像下面这样的 s,它可能是可以接受的,但是如果对一堆嵌套的IO (Either String Int)s进行嵌套,是否有处理此类类型的通用模式。例如,如果binfunctionDoSomething再次是 a(Either a b)并且在成功时获取值并再次用它做某事将是另一个这样的case。是否有我可以使用的高阶函数?我对 monad 转换器还不满意,不确定它们是否可以用来处理这个特定的 monad 堆栈。如果它们可以在这里使用,有没有办法在不使用它们的情况下做到这一点。
import Control.Monad
functionCreate :: Int -> IO (Either String Int)
functionDoSomething :: Int -> IO b
functionUse :: IO ()
functionUse = do
created <- functionCreate 10
case created of
(Right v) -> void $ functionDoSomething v
_ -> return ()
Run Code Online (Sandbox Code Playgroud) 我正在阅读Haskell书中关于monad变换器的内容.
作者提到了以下内容:
Monad怎么样?组成两个具有Monad实例的任意数据类型没有问题.当我们使用Compose with Maybe和list时,我们已经看到了这一点,它们都定义了Monad实例.但是,这样做的结果并没有给你一个Monad.
问题归结为缺乏信息.Compose正在使用的两种类型都是多态的,所以当你尝试为Monad编写bind时,你试图将两个多态绑定组合成一个组合绑定.事实证明,这是不可能的:
Run Code Online (Sandbox Code Playgroud){-# LANGUAGE InstanceSigs #-} -- impossible. instance (Monad f, Monad g) => Monad (Compose f g) where return = pure (>>=) :: Compose f g a -> (a -> Compose f g b) -> Compose f g b (>>=) = ???这些是我们尝试组合的类型,因为并且必然都是具有自己的Monad实例的monad:
Run Code Online (Sandbox Code Playgroud)Monad f => f a -> (a -> f b) -> f b Monad g => g a -> (a -> g b) -> g b从那些,我们正在尝试编写这个绑定:
Run Code Online (Sandbox Code Playgroud)(Monad f, Monad g) => …