Backwards是否承认Monad实例?

时间:2015-12-15 20:25:45

标签: haskell monads

我刚刚在haskell-cafe上问过这个问题,但我想我也可以在这里问一下。 Backwards m的以下Monad实例是否有效?

{-# Language RecursiveDo #-}

import Control.Applicative.Backwards
import Control.Monad.Fix

instance MonadFix m => Monad (Backwards m) where
  m >>= f = Backwards $
    do
      fin <- forwards (f int)
      int <- forwards m
      pure fin

如果是这样,我还可以添加吗?

instance MonadFix m => MonadFix (Backwards m) where
  mfix f = Backwards $ mfix (forwards . f)

2 个答案:

答案 0 :(得分:3)

不,它无效; monad法则充其量只能以某种近似的方式持有。正如Petr Pudlák's answer所示,当http://username:password@myserver.com/api.php 在其参数中严格时,Backwards m >>= f表现不佳。

根据monad法律,

f

但是有了这个例子,如果我没有弄错的话,

pure () >>= (\() -> m)   =   m

如果潜在的monad是&#34; strict&#34; (即,它的pure () >>= (\() -> m) = Backwards $ do fin <- forwards (int `seq` m) int <- pure () pure fin = Backwards $ fmap fst $ mfix $ \ ~(_, int) -> do fin <- forwards (int `seq` m) pure (fin, ()) 在左操作数上是严格的),这将会发散。

答案 1 :(得分:2)

对于这个f需要是懒惰的,也就是说,效果不能取决于参数。 docs

  

mfix f仅执行一次动作f,最终输出作为输入反馈。因此f不应该严格,因为mfix f会分歧。

如果您的案例f中的m >>= f严格,那么Buf会传递给mfix

让我们考虑mreadLine >>= putStrLn的实际示例。颠倒顺序意味着“打印数据,然后读取它”。除非>>=后面的函数的效果不依赖于输入,否则这会有所不同。