【问题标题】:MonadFix instance for [][] 的 MonadFix 实例
【发布时间】:2016-11-05 05:51:44
【问题描述】:

实例定义为

instance MonadFix [] where
  mfix f = case fix (f . head) of
             []    -> []
             (x:_) -> x : mfix (tail . f)

但是对于被视为非确定性计算的[] monad,我无法理解其背后的直观含义。在mfix f 函数中,f 的参数不能严格,所以它不能检查参数。而且根据定义,它也不能在其输出的任何地方使用该参数,否则在某些时候它会达到fix (f . head) 并发散。那么除了mfix (const someList) 之外,mfix 对于列表还有什么用处(或很好的例子)吗?

【问题讨论】:

  • f的论点不能严格”并不意味着if不能懒惰地检查论点。
  • @Bergi 好点。你能详细说明一个例子吗?

标签: list haskell monads monadfix


【解决方案1】:

这样说可能最容易。完全定义了mfix f的函数f是那些f x的spine不依赖于x的函数,所以可以写成这样的形式

f x = [f1 x, ..., fn x]

对于一些n(可能是无穷大)和一些f1,...,fn。那么

mfix f = [fix f1, ..., fix fn]

(当然要真正完全定义,每个fix fi也必须定义)。


mfix 可以被认为是非确定性地为您提供非确定性函数的不动点。相当严格的限制是非确定性计算的形状不能以任何方式依赖于输入。我们似乎需要对计算进行某种限制才能开始,但您可能希望至少能够有条件地终止计算的一个分支(例如,如果某个中间计算是否定的)。我一直认为应该可以通过使用不同的非确定性单子以这种方式使用mfix,其选择操作不是关联的,但从未解决过细节。

【讨论】:

  • 所以你是说像我第一次给出的例子是这个mfix 没有分歧的唯一用法?
【解决方案2】:

如果您将所有fix 变体实际与严格的函数一起使用,它们都会出现问题,但这在实际用例中通常不是问题:@ 987654322@ 基本上都是函数类型,任何 lambda 都已经在 NF 中了。

所以,至于具体的用途……嗯,这至少是收敛的东西

f :: (Int -> Int) -> [Int -> Int]

f f' = [\x -> if x>0 then f' (x-1) * i else 1 | i<-[0..]]

f基本上是生成幂函数列表。

GHCi> take 20 $ mfix f <*> [1,2] [0,0,1,1,2,4,3,9,4,16,5,25,6,36,7,49,8,64,9,81]

我不确定这实际上有什么用,但它确实有非常有趣的行为。

我刚刚注意到这是一个不好的例子,因为它实际上等同于单个fix (f . head)。嗯……


您似乎很正确:在a -> [a] 的情况下,它一个问题,因为没有明显的方法来制作列表结构依赖于论点而不变得严格。

【讨论】:

    猜你喜欢
    • 2012-06-19
    • 2011-07-18
    • 2014-11-06
    • 2021-03-22
    • 2014-11-07
    • 2015-05-23
    • 2018-05-29
    • 2013-01-16
    • 2013-03-11
    相关资源
    最近更新 更多