【问题标题】:a fixed point for fix :: Eq a => (a -> a) -> a -> a修复的固定点 :: Eq a => (a -> a) -> a -> a
【发布时间】:2019-05-04 03:23:17
【问题描述】:

大家好,我正在尝试实现高阶函数修复,它从初始点 x 计算任意函数 f :: a -> aattractive fixed point。也就是说,对于给定的fx,形式为fᴷ(x) 的不动点。

-- CONTRACT
fix :: Eq a => (a -> a) -> a -> a
-- DEFINITION [TODO: Implement fix]
fix f x  = ?

我目前的尝试是:

fix f x | f x == x = x
        | otherwise = fix f x
    where x = f x

注意:您的 如果函数从一开始就没有收敛,函数将不会终止 点。 有人能帮助我吗 ?我试过了,但它没有返回任何东西

【问题讨论】:

  • 你能分享一下你的尝试吗?
  • 修复 f x | f x == x = x |否则 = 修正 f x 其中 x = f x
  • 你的函数类型不对。定点组合器的类型为fix :: (a -> a) -> a
  • @AaditMShah 这是一个很好的签名,它只是一个不同于 PL 人喜欢的fix
  • 不,没有错。这是一个家庭作业!

标签: haskell fixpoint-combinators


【解决方案1】:

一个常见的误解是,当您编写 x = ... 时,您在 Haskell 中分配一个值。在 Haskell 中,一个赋值,一个声明一个。

这意味着基本上你在where 子句中构造了一个变量x,它不是函数头部的x,所以类似于:

fix :: Eq a => (a -> a) -> a -> a
fix f _ | f x == x = x
        | otherwise = fix f x
    where x = f x

您在这里定义了 x 本身:x = f x,这意味着如果 Haskell 旨在评估它,它将开始计算 f(f(f(f(f(f(...)))))),但不检查 固定点 em> 已到达。

因此解决方案是引入一个新变量,例如x2,然后像这样使用:

fix :: Eq a => (a -> a) -> a -> a
fix f x | x == x2 = x
        | otherwise = fix f x2
    where x2 = f x

所以这里x2 是下一个x。给定x == x2,我们返回x(或x2),如果不是,我们计算fx2的不动点,所以我们在“不动点探索”中前进了一步”。

【讨论】:

  • @Amerov:为什么(*2)的不动点是3?固定点的想法是f x == x,但是(*2) 12 == 24,而不是12
  • @Amerov (*2) 的不动点为0,不吸引人,所以任何不是0开头的参数都不会达到。
  • @Amerov fix (*2) 0 会起作用。或例如fix (`div` 2) 100。或者let collatz x | even x = div x 2 | x <= 1 = 1 | otherwise = (3*x+1),然后是fix collatz 99
  • @Amerov 是的,为什么不呢? StringEq 的一个实例。你只需要设计一个字符串到字符串的函数,它有一个(有吸引力的)固定点。
  • 尝试fix cos 1 查找 Dottie 号码。
【解决方案2】:

为下一步的迭代取一个不同的名称,如下所示:

where x' = f x

(而不是where x = f x)。现在查看现有代码的其余部分,对于每次出现的x,问问自己:我是指这里的x,还是x'

【讨论】:

  • 不应该是where x' = f x'吗?
  • @AaditMShah:不,从那以后你递归调用修复点,而不进行适当的相等性检查。
  • @WillemVanOnsem 不,你不知道。 Haskell 很懒。
  • @AaditMShah:我知道,但同样,固定点,就像库中定义的那个与这个相关,但不是同一个。库中的fix 更多,如果你有fs 发出一些东西,例如f = (1:),以生成1s 的无限列表。
  • 不是因为 Haskell 很懒,x' = f x 就相当于x' = f x
【解决方案3】:

您已经有了如何从头开始编写fix 的答案。如果你想尝试使用一些标准的 Haskell 函数,我建议你查看函数 until

until :: (a -> Bool) -> (a -> a) -> a -> a

注意until 的类型与您想要的类型非常相似。它只需要一个a -> Bool 形式的额外参数。表达式until p f x 从初始点x 开始迭代应用f,直到满足某个条件p。你应该可以很容易地在表格中写fix

fix = until p 

对于某些功能p :: a -> Bool。现在你只需要实现这个停止条件p,它检查你计算的点y是否是f的固定点,即如果f y == y

【讨论】:

    猜你喜欢
    • 2017-11-21
    • 1970-01-01
    • 2017-01-30
    • 1970-01-01
    • 2011-03-20
    • 1970-01-01
    • 1970-01-01
    • 2016-02-17
    • 1970-01-01
    相关资源
    最近更新 更多