首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >向后允许Monad实例吗?

向后允许Monad实例吗?
EN

Stack Overflow用户
提问于 2015-12-16 04:25:45
回答 2查看 115关注 0票数 7

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

代码语言:javascript
复制
{-# 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

如果是这样的话,我还可以加上这个吗?

代码语言:javascript
复制
instance MonadFix m => MonadFix (Backwards m) where
  mfix f = Backwards $ mfix (forwards . f)
EN

回答 2

Stack Overflow用户

发布于 2015-12-16 05:54:00

不,它是无效的;单子定律充其量是以某种近似的方式成立的。正如Petr Pudlák's answer所显示的那样,当Backwards m >>= f的参数很严格时,f的行为并不是很好。

根据单元律,

代码语言:javascript
复制
pure () >>= (\() -> m)   =   m

但在这个例子中,如果我没记错的话,

代码语言:javascript
复制
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, ())

如果底层的monad是“严格的”(即,它的>>=在其左操作数中是严格的),这将会发散。

票数 3
EN

Stack Overflow用户

发布于 2015-12-16 05:13:40

对于这个f,需要是惰性的,也就是说,效果不能依赖于参数。docs

mfix f只执行一次动作f,最终的输出作为输入反馈。因此,f不应该是严格的,因为那样mfix f就会发散。

Buf如果在本例中为fm >>= f将是严格的,那么传递给mfix的块也将是严格的。

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

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34298726

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档