【问题标题】:simultaneous recurrence relations in haskellhaskell中的同时递归关系
【发布时间】:2017-12-28 17:57:20
【问题描述】:

是否可以在haskell中建立一个同时递归关系的系统?我正在尝试实现

a(n)=3a(n-1)+2b(n-1)

b(n) = a(n-1) + 2b(n-1)

输入:

 a n = 3 * a (n-1) + 2 * b (n-1)

输出:

<interactive>:103:25: error: Variable not in scope: b :: t -> a

所以,我既不能在不先定义 b 的情况下定义 a,也不能在不先定义 a 的情况下定义 b。我不确定这样做是否可行?

PS:我在gchi工作

【问题讨论】:

  • 您要查找的术语是mutual recursion,它可以在haskell 中找到。如果您使用 GHCi,使用 :set +m 打开多行模式并使用 let 同时定义两者可能会有所帮助
  • 另请注意,此类定义将导致指数复杂度算法。不要期望它可以合理地处理大输入值。
  • @chi 但编译器不会自动为我们处理吗?
  • 编译器不会把低效的算法变成高效的。如果你需要一个高效的算法,你需要将它提供给编译器。
  • @chi 我不知道你是否是 Haskell 方面的专家。但是 Haskell 是一种纯粹的函数式语言,这意味着在 Haskell 中你必须递归地定义函数,没有 for 循环。不过听说haskell编译器很智能,会决定如何高效编译,函数不会按照你想的顺序互相调用。

标签: haskell


【解决方案1】:

在 Haskell 中,定义的顺序无关紧要。您可以在b 之前定义a 或在a 之前定义b,在这两种情况下它们都可以相互引用:

a n = 3 * a (n-1) + 2 * b (n-1)
b n = a (n-1) + 2 * b (n-1)

如果您在 GHCi 中工作(请澄清这一点),那么是的,它不会单独接受 a 的定义,因为它不知道 b 是什么。但是,您可以将 GHCi 两个定义放在一起,方法是将它们括在 :{ ... :} 中,如下所示:

*Prelude> :{                             
*Prelude| a n = 3 * a (n-1) + 2 * b (n-1)
*Prelude| b n = a (n-1) + 2 * b (n-1)    
*Prelude| :}

最后,我必须注意,这些定义,如所写,将产生一个无限循环:没有任何情况(即没有输入)ab 不递归地调用自己。这意味着,一旦你打电话给他们中的任何一个,他们就会永远互相打电话。

要解决这个问题,您需要提供一个基本案例 - 一个输入或一组输入,其中函数不调用自身,例如:

a 0 = 1
a n = 3 * a (n-1) + 2 * b (n-1)

b 0 = 1
b n = a (n-1) + 2 * b (n-1)

(我无法判断我是否提供了正确的基本案例,因为我不知道您的原始问题是什么,因此无法说出您的上下文中什么是“正确的”;我提供的基本案例是只是示例来说明如何完成)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-01-09
    • 2012-04-08
    • 1970-01-01
    • 2019-10-18
    • 2015-03-08
    • 2020-11-09
    • 2017-06-04
    • 1970-01-01
    相关资源
    最近更新 更多