- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
书中Real World OCaml ,作者阐述了为什么 OCaml 使用 let rec
来定义递归函数。
OCaml distinguishes between nonrecursive definitions (using let) and recursive definitions (using let rec) largely for technical reasons: the type-inference algorithm needs to know when a set of function definitions are mutually recursive, and for reasons that don't apply to a pure language like Haskell, these have to be marked explicitly by the programmer.
强制执行 let rec
而纯函数式语言则不执行的技术原因是什么?
最佳答案
当您定义函数定义的语义时,作为语言设计者,您可以选择:要么使函数的名称在其自身范围内可见,要么不可见。两种选择都是完全合法的,例如 C 系列语言远非功能性的,但仍然具有在其范围内可见的定义名称(这也扩展到 C 中的所有定义,使得 int x = x + 1
合法)。 OCaml 语言决定给我们额外的灵 active ,让我们自己做出选择。这真的很棒。他们决定默认使其不可见,这是一个相当不错的解决方案,因为我们编写的大多数函数都是非递归的。
关于引用,它并不真正对应于函数定义 - rec
最常见的用法关键词。它主要是关于“为什么函数定义的范围没有扩展到模块的主体”。这是一个完全不同的问题。经过一番研究,我发现了一个非常similar question ,有 answer ,这可能会让你满意,引用它:
So, given that the type checker needs to know about which sets ofdefinitions are mutually recursive, what can it do? One possibility isto simply do a dependency analysis on all the definitions in a scope,and reorder them into the smallest possible groups. Haskell actuallydoes this, but in languages like F# (and OCaml and SML) which haveunrestricted side-effects, this is a bad idea because it might reorderthe side-effects too. So instead it asks the user to explicitly markwhich definitions are mutually recursive, and thus by extension wheregeneralization should occur.
即使没有任何重新排序,使用任意非纯表达式,可能会出现在函数定义中(定义的副作用,而不是评估),也不可能构建依赖关系图。考虑从文件中解码并执行函数。
总而言之,let rec
有两种用法构造,一是创建一个自递归函数,比如
let rec seq acc = function
| 0 -> acc
| n -> seq (acc+1) (n-1)
另一种是定义相互递归函数:
let rec odd n =
if n = 0 then true
else if n = 1 then false else even (n - 1)
and even n =
if n = 0 then false
else if n = 1 then true else odd (n - 1)
在第一种情况下,没有技术原因坚持使用一个或另一个解决方案。这只是一个品味问题。
第二种情况比较困难。推断类型时,您需要将所有函数定义拆分为由相互依赖的定义组成的簇,以缩小类型环境。在 OCaml 中,它更难实现,因为您需要考虑副作用。 (或者您可以继续而不将其拆分为主要组件,但这将导致另一个问题 - 您的类型系统将受到更多限制,即,将不允许更多有效的程序)。
但是,重新审视最初的问题和 RWO 的引用,我仍然非常确定添加 rec
没有技术原因。旗帜。考虑一下,SML 也有同样的问题,但仍然有 rec
默认启用。 有技术原因,let ... and ...
用于定义一组相互递归函数的语法。在 SML 中,此语法不需要我们输入 rec
OCaml 中的 flag 确实如此,从而为我们提供了更大的灵 active ,例如能够使用 let x = y and y = x
交换到值。表达。
关于haskell - 非纯函数式语言 OCaml 出现 'let rec' 的原因是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28796904/
为什么第一个定义会被拒绝,而第二个定义会被接受,最好的直觉是什么? let rec a = b (* This kind of expression is not allowed as right-h
我在 linux 机器上有我的 vmstat 输出: # cat vmstat.out procs -----------memory---------- ---swap-- -----io----
我正在使用av基础框架来录制视频。我将视频输出的最大持续时间设置为 10 秒。 是否可以以 10 秒的间隔循环录制而不是停止录制。 我的目标是仅存储最近 10 秒的视频输出。 谢谢! 最佳答案 就您而
在箭头符号中,您可以使用 rec 关键字来编写递归定义。例如: rec name ArrowLoop a where loop :: a (b,d) (c,d) -> a b
我一直认为在 F# 中我们需要使用 rec每个递归函数的关键字,例如: let rec factorial = function | 0 -> 1 | k when k > 0 -> k * (fa
我正在使用java语言开发一个android应用程序。 该方法的主体如下:字符串“3”作为第一个参数传递给它 - nextCmdId,但在该方法中它结果是一个 Rect,并且应用程序崩溃了。 很奇怪!
我想知道 F# 如何实现 let rec ,我找不到答案。作为前言,我将介绍 Scheme 如何实现 letrec : 在方案中,let只是定义 lambda 并应用它的语法糖:(let ((x 1)
这个函数是尾递归的吗? let rec rec_algo1 step J = if step = dSs then J else let a = Array.init
我有一个这样的数据结构: array (size=10) 1 => array (size=2) 'fdate' => string '11/05/12' (length=8
我正在学习Json4s图书馆。 我有一个像这样的 json 片段: { "records":[ { "name":"John Derp",
我需要将一列数据添加到 numpy rec 数组中。我在这里看到了很多答案,但它们似乎不适用于仅包含一行的记录数组... 假设我有一个记录数组x: >>> x = np.rec.array([1, 2
我正在研究推荐系统,计算的一部分是将权重作为许多共同评分的项目添加到距离度量中。考虑下面的矩阵: 行代表用户,列代表项目。例如第一行,该用户给产品A打了2分,没有评价产品B。然后产品C得到了3分,产品
我有一个 Numpy rec 数组,我想从中执行一些类似于 SQL 的快速查询:SELECT * where array['phase'] == "P"。我想获得一个记录数组作为输出,每一行对应于原始
我正在通过 ffpmeg 读取音频流,如下所示: ffmpeg -i http://icecast.radiovox.org:8000/live.ogg -f mp3 filename 并希望将其通过
我不确定这是否是一个愚蠢的问题,但我正在浏览 VS 2010 附带的教程,并且有一个这样的函数: let rec factorial n = if n=0 then 1 else n * factor
我通过Im2rec创建了Mxnet Rec数据。我想将其输入Tensorflow。是否可以 ?我该怎么做?有什么想法吗? 最佳答案 您或许可以提供数据。您将需要使用 MXNet 迭代器从记录中获取数据
在某些项目中更新到 C# 6 和 VS2015 后,我开始看到很多构建警告,如下所示: RECS0119 'string.Compare' is culture-aware RECS0017 Poss
我正在设置 Jenkins View 并希望使用 Regex 自动选择匹配的作业。要选择的工作都有一个前缀,如“rec-01-”、“rec-24-”、“rec-98-”等。唯一的区别是两位数。 我试过
这些天我正在学习 OCaml 并遇到了这个问题: OCaml 对它可以放在 let rec 右侧的内容有限制。像这个 let memo_rec f_norec = let rec f = memoiz
书中Real World OCaml ,作者阐述了为什么 OCaml 使用 let rec 来定义递归函数。 OCaml distinguishes between nonrecursive defi
我是一名优秀的程序员,十分优秀!