首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >递归-Do可以去糖化吗

递归-Do可以去糖化吗
EN

Stack Overflow用户
提问于 2020-03-24 02:53:51
回答 1查看 87关注 0票数 3

可以将递归do语句去丑化为一系列>>=语句吗?如果是这样的话,去掉reverse state monad's definition for >>=代码后会是什么样子呢?

代码语言:javascript
复制
instance MonadFix m => Monad (StateT s m) where
  return x = ...
  m >>= f = StateT $ \s -> do
    rec
      (x, s'') <- runStateT m s'
      (x', s') <- runStateT (f x) s
    return (x', s'')
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-03-24 03:31:15

递归--不仅对一系列的>>=调用进行去糖化,而且只要存在递归,就可以对mfix调用进行去糖化。正是在mfix调用中,通过技术上称为“魔法仙尘”的方式实现了整个递归。

不过说真的,它是如何发生的对于每个monad来说都是不同的,这就是为什么它是一个类MonadFix而不仅仅是一个函数。但重要的一点是,它可以“神奇地”将您自己的结果作为参数传递给您,这只可能是由于Haskell的懒惰,因此必须小心处理。

一般来说,就像这样:

代码语言:javascript
复制
do
    rec 
        x <- f y
        y <- g x
    return $ h x y

将代码添加到以下代码中:

代码语言:javascript
复制
mfix (\ ~(x, y) -> do
    x' <- f y
    y' <- g x'
    return (x', y')
)
>>= (\(x, y) -> h x y)

因此,将其应用于反向状态定义,将如下所示:

代码语言:javascript
复制
m >>= f = StateT $ \s ->
  mfix (\ ~((x, s''), (x',s')) -> do
    (x0, s0'') <- runStateT m s'
    (x0', s0') <- runStateT (f x0) s
    return ((x0, s0''), (x0', x0'))
  )
  >>= (\(x, s''), (x',s') -> return (x', s''))

从这里开始,我们可以像往常一样去掉常规的do

代码语言:javascript
复制
m >>= f = StateT $ \s ->
  mfix (\ ~((x, s''), (x',s')) ->
    runStateT m s' >>= \(x0, s0'') ->
    runStateT (f x0) s >>= \(x0', s0') ->
    return ((x0, s0''), (x0', x0'))
  )
  >>= (\(x, s''), (x',s') -> return (x', s''))

(也就是说,除非我搞砸了一些东西--很多滴答声飞来飞去:)

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

https://stackoverflow.com/questions/60819886

复制
相关文章

相似问题

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