Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 围绕IO创建包装器Monad_Haskell_Io_Monads - Fatal编程技术网

Haskell 围绕IO创建包装器Monad

Haskell 围绕IO创建包装器Monad,haskell,io,monads,Haskell,Io,Monads,假设我想创建一个执行IO操作的包装Monad,并将其包装如下。sequence操作符(>>)工作得很好,但是我很难实现返回和>= 我尝试了return x=DelayedAction(return x),但没有得到正确的类型 newtype DelayedAction a = DelayedAction {action :: IO a} instance Functor DelayedAction where fmap = liftM instance Applicative Delay

假设我想创建一个执行IO操作的包装Monad,并将其包装如下。sequence操作符(>>)工作得很好,但是我很难实现
返回
>=

我尝试了
return x=DelayedAction(return x)
,但没有得到正确的类型

newtype DelayedAction a = DelayedAction {action :: IO a}

instance Functor DelayedAction where
  fmap = liftM

instance Applicative DelayedAction where
  pure = return
  (<*>) = ap

instance Monad DelayedAction where
  return x = undefined
  (DelayedAction firstIO) >>= f = undefined

  (DelayedAction firstIO) >> (DelayedAction secondIO) =
    DelayedAction
      ( do
          firstIO
          threadDelay 1000000
          secondIO
      )
newtype DelayedAction a=DelayedAction{action::IO a}
实例函子DelayedAction,其中
fmap=liftM
实例应用程序延迟动作,其中
纯=返回
()=ap
实例Monad DelayedAction,其中
返回x=未定义
(DelayedAction firstIO)>>=f=未定义
(DelayedAction firstIO)>>(DelayedAction secondIO)=
延迟行动
(做
第一
线程延迟1000000
第二
)

@Aplet123和@leftaroundabout澄清,这不可能是真正的单子,因为它不能遵循单子定律。尽管如此,我还是想出了一个令编译器满意的解决方案。教了我很多关于单子、类型类、类型、do符号等的知识

instance Monad DelayedAction where
  return x = DelayedAction (return x)

  da >>= f =
    DelayedAction
      ( do
          firstIOValue <- action da
          threadDelay 1000000
          (action . f) firstIOValue
      )

这不符合单子定律。如果每次绑定都添加延迟,
m>=return
将不等于
m
。另见:和。这并不是说写一个实现是不可能的,只是意味着你不应该这样做。但是,在这种情况下,可以通过在每个操作(返回除外)中设置延迟来解决此问题。实现这一点的最实际的方法是批量复制monad实例,但不导出
DelayedAction
构造函数,而只导出
DelayedAction a=threadDelay 1000000>>a
@leftaroundabout-这很有趣,可以扩展吗?“批量复制monad实例”是什么意思?
da >>= f =
  DelayedAction
    ( action da >>= (\firstIOValue -> threadDelay 1000000 >> (action . f) firstIOValue)