【问题标题】:typeclass for repetitive actions until fixed point重复动作的类型类,直到固定点
【发布时间】:2014-03-02 16:04:34
【问题描述】:

我注意到执行一个动作直到它停止产生某些效果的一种常见模式,当人们知道这表示一个固定点时(即,不会有未来的效果)。有这个的类型类吗?

这是否被 MonadFix 覆盖?看代码,似乎是这样,但我被wiki page吓跑了“很容易看到“递归”并猜测它意味着递归或重复执行动作。不。”

在我看来,不动点也是身份的对偶。也就是说,当与非身份结合时,身份会消失(0 表示 (+),1 表示 (*),[] 表示追加等)。而固定点会导致任何非固定点在下面的“放松”操作下消失。有没有办法将这种二元性形式化,这样做有用吗?即,MonadPlus 和/或 Monoid 与 MonadRelax 之间是否存在关系?

最后,我注意到放松几乎是一种展开/变形。这样表达会更好吗?

{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies #-}

import Control.Monad.Loops (iterateUntilM) -- cabal install monad-loops

-- states that relax to a fixed point under step
class Monad m => MonadRelax m s | s -> m where
isFixed :: s -> Bool
step :: s -> m s -- often (not always): step s = return s iff isFixed s

relax :: MonadRelax m s => s -> m s
relax = iterateUntilM isFixed step

【问题讨论】:

  • step s == s 的类型不是很好,但你可能有step s == return s,只要Eq a => Eq (m a)。另外,将fundep设为s -> m也很奇怪。
  • 是的,我的意思是返回有点隐含。 Fundep 是如此 isFixed 可以查找它的实例,即使它没有提到类型 m(感谢 #haskell 上的 johnw)。
  • 你的relax操作,严格来说,不会“执行[e]一个动作,直到它停止产生效果”——它观察的是结果step,不一定是它的影响。您是否在做出将效果和结果等同起来的假设?如果是这样,您可能需要澄清这一点。
  • 是的,我的意思是“停止具有某些效果”,这通常但不一定意味着改变结果。我猜在那种情况下,在(Eq s)下,mfix(或其他)可以自动找到固定点,我们不需要isFixed?不过,我不想将其限制在这种情况下。
  • 我不明白为什么MonadRelaxiterateUntilM 好。事实上,情况似乎更糟;一旦我们知道它的类型,是否有理由相信只有一种好方法来步进值?

标签: haskell recursion fixpoint-combinators unfold monadfix


【解决方案1】:

你要的,其实是一个普通的fix

cd :: (Monad m) => Int -> Int -> m Int
cd = fix (\f c i -> if i == 0 then return c else f (c+i) (i-1))

这将重复计算,直到 i 变为 0。(我添加了 c 以进行有意义的计算;但您可以假设 s=(Int,Int) 其中一个是滚动总和,另一个是计数器)

> cd 0 4 :: [Int]
[10]

这与:

relax = fix (\f s -> if isFix s then return s else f (step s))

我相信,这就是iterateUntilM的定义。

【讨论】:

  • 我一定是误会了——我希望 step 能够产生效果,并且 afaict,isFixed 和 step 的这些类型看起来是错误的:relax :: Monad m => a -> m arelax = fix (\f s -> if isFixed s then return s else f (step s))step = undefinedisFixed = undefined@987654333 @:t isFixed -> isFixed :: a
  • @user1441998 好吧,那么,step s >>= f
  • 效果很好,但我不同意。 fix :: (a -> a) -> a,但是你传递了两个参数的函数。我可以看到a = b -> mb 的类型。但是我们如何看待您的f?某种空动作,只是不像返回那样空?反复出现的动作?这只是您知道的一个技巧,还是有办法对此解决方案进行推理?既然涉及效果,为什么不需要 MonadFix,即,要应用 MonadFix 还需要做什么? btw 身份和不动点的潜在二元性呢?变形总是可以用固定来表示吗?
  • @user1441998 :) 这值得长篇大论。最好这样想:cd = fix g 表示cd = g cd。所以我传递给fix 的lambda 的第一个参数f 实际上是cdf 不是空操作。这里的技巧是对cd 的递归调用与>> 绑定在一起,后者结合了每个调用的操作。 MonadFix 用于不同的模式。同一性与固定点有关,就像同构与同一性有关。 fix 并不总是变形,但变形总是 fix
  • @user1441998 回复:固定点 Varmo Vene 在他的论文中对此事进行了很好的分类处理。
猜你喜欢
  • 2011-02-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-01
  • 2014-12-11
  • 1970-01-01
  • 2019-08-03
相关资源
最近更新 更多