首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Haskell非函数递归(或值递归或递归let绑定)

Haskell非函数递归(或值递归或递归let绑定)
EN

Stack Overflow用户
提问于 2021-05-01 21:32:02
回答 1查看 185关注 0票数 0

我对Haskell很陌生,读过Haskell的基本原理。

在第10章第378页中,我发现了一个新的语法。

代码语言:javascript
运行
复制
fibs = 1 : scanl (+) 1 fibs

似乎fibs是一个函数bcs,它正在被使用或被调用。

但是它的类型是fibs :: Num a => [a],所以它是一个值。

如何在它自己的定义中访问一个值?

如果我真的想看看里面的谎言,它就会朝着无穷远的方向打印出来。

和其他的例子i = 1 + i,它是完全有效的语法,

但是当我在旁边运行它时,它也会停止它。

  • 如果它不是递归,它是什么类型的递归?
  • 执行流程是什么?
  • i完全不被分配时,它如何能够在右侧访问?
  • i第一次的价值是什么?
  • i在右边的价值是多少?

有能帮上忙的文章吗?

EN

Stack Overflow用户

发布于 2021-05-01 21:55:23

在许多(大多数?)语言函数是一种“特殊”的值,在语言语法和语义上具有特殊的地位。

在哈斯克尔,没那么多。它们与非函数共享许多属性。特别是:

  • 我们可以将函数(和非函数)作为参数传递给函数。
  • 我们可以从函数返回函数(和非函数)。
  • 我们可以将函数(和非函数)放入容器中,如列表、对等。
  • 我们可以递归地定义函数(和非函数)。

如果您不习惯,最后一点可能会令人费解,但是没有理由只在像Haskell这样的惰性语言中定义函数值时才允许递归。

例如,可以通过允许1:1:1:....来定义无限列表list = 1 : list。如果您只能理解函数的递归定义,只需知道它与list() = 1 : list()类似,除非list不是一个函数,而是一个列表。

您还可以尝试理解1:2:3:4:....可以递归地定义为list = 1 : map (+1) list。事实上,展开我们得到的定义:

代码语言:javascript
运行
复制
list
= 1 : map (+1) list
= 1 : map (+1) (1 : map (+1) list)
= 1 : 2 : map (+1) (map (+1) list)
= 1 : 2 : map (+1) (map (+1) (1 : map (+1) list))
= 1 : 2 : 3 : map (+1) (map (+1) (map (+1) list))
...

请注意,上面的定义“工作”是因为它可以在递归地需要自己的值之前生成值的一部分。在您提到的i = i + 1示例中,这种情况不会发生,因为i + 1需要立即获得i的值,然后才能生成输出的任何部分。(至少在标准整数类型上是这样的。)因此,它具有与无限递归函数(如i() = i() + 1 )相同的行为。

票数 7
EN
查看全部 1 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67351024

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档