【问题标题】:Iterate Calculation in Haskell在 Haskell 中迭代计算
【发布时间】:2017-11-08 18:29:47
【问题描述】:

我是 Haskell 的初学者,我正在尝试在 Haskell 中创建一个无限列表,其中下一项通过以下公式找到

xn+1 = (xn + const / xn) div 2.

我一直在研究 iterate 命令,因为我想再次应用相同的函数来生成下一个答案。

然后我将使用 take 从列表中选择一定数量的元素。

但是我不确定在使用 iterate 时如何表示 xn。

我开始写take 10 (iterate (xn +5 /xn div 2) 1),我知道我需要替换 xn 但不确定用什么替换。

有人可以给我建议吗?

【问题讨论】:

  • 它是div (xn + const / xn) 2div 不是运算符,因此您不能使用中缀(没有反引号)。
  • 我一直在使用带有反引号的 div,我在这里删除了它们,因为当我这样做时它会将 div 从代码列表中删除。
  • @JamesHamish 你必须通过在它前面加上一个反斜杠来转义引用:`div`
  • 通过在其周围放置双反引号来引用包含反引号的代码。

标签: haskell


【解决方案1】:

你基本上描述了一个函数:

next xn = (xn + c) / (2*xn)

使用cconstconst 是 Prelude 中的一个函数,因此不要使用该名称)。或者作为 lambda 表达式:

\xn -> (xn + c) / (2*xn)

c 你的常量。所以现在我们可以将它注入iterate:

take 10 (iterate (\xn -> (xn + 5) / (2*xn)) 1)

使用c=5,我们得到:

Prelude> take 10 (iterate (\xn -> (xn + 5) / (2*xn)) 1)
[1.0,3.0,1.3333333333333333,2.375,1.5526315789473684,2.110169491525424,1.684738955823293,1.9839094159713946,1.7601381796335236,1.9203430326819695]

如果你想计算整数的值,你可以使用:

\xn -> div (xn + c) (2*xn)

这会产生:

Prelude> take 10 (iterate (\xn -> div (xn + 5) (2*xn)) 1)
[1,3,1,3,1,3,1,3,1,3]

如果要对计算后的结果进行四舍五入,可以使用floor

\xn -> floor ((fromIntegral xn + 5) / (2* fromIntegral xn))

这会产生:

Prelude> take 10 $ iterate (\xn -> floor ((fromIntegral xn + 5) / (2* fromIntegral xn))) 1
[1,3,1,3,1,3,1,3,1,3]

【讨论】:

  • 这个问题是我使用 div 进行整数除法和四舍五入,当你划分时你使用 /
  • 你不能同时使用div/获取相同的类型,因为(/) :: Fractional f => f -> f -> fdiv :: Integral i => i -> i -> i。虽然从技术上讲我们可以构造这样一个类型,但同时拥有IntegralFractional 的类型是很奇怪的。
  • @JamesHamish 检查括号是否真的是您想要的。浮点数比整数更有意义。
【解决方案2】:

只需使用lambda 函数:

mySeq = iterate (\xn ->(xn + 5 `div` xn) `div` 2) 1

你有一个live example

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-01-21
    • 2016-12-23
    • 1970-01-01
    • 2021-08-01
    • 2020-08-09
    • 1970-01-01
    相关资源
    最近更新 更多