- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
一旦编译并运行,这会像尾调用一样吗?
let rec f accu = function
| [] -> accu
| h::t -> (h + accu) |> f <| t
也许有一种简单的方法可以测试我不知道的行为,但这可能是另一个问题。
最佳答案
我认为如果您不使用流水线运算符,这会更容易理解。实际上,这两个流水线运算符被定义为inline
。 , 所以编译器会将代码简化为如下(而且我认为这个版本也更易读和更容易理解,所以我会这样写):
let rec f accu = function
| [] -> accu
| h::t -> f (h + accu) t
现在,您可以阅读 tail-call on Wikipedia 的定义,它说:
A tail call is a subroutine call that happens inside another procedure as its final action; it may produce a return value which is then immediately returned by the calling procedure.
所以是的,调用 f
最后一行是尾调用。
如果你想分析原始表达式 (h + accu) |> f <| t
(不知道流水线运算符是内联的),那么这实际上变成了 ((h + accu) |> f) <| t
.这意味着表达式调用 <|
带有两个参数的运算符并返回结果 - 所以调用 <|
是尾调用。
<|
运算符定义如下:
let (<|) f a = f a
现在,调用 f
流水线运算符内部也是一个尾调用(对于其他流水线运算符也是如此)。
总而言之,如果编译器没有进行内联,您将有一个包含三个尾调用的序列(使用 .NET .tail
指令编译以确保 .NET 执行尾调用)。但是,由于编译器执行内联,它会看到您有一个递归尾调用( f
调用 f
),这可以更有效地编译成一个循环。 (但是跨多个函数或运算符的调用不能轻易使用循环。)
关于f# - 执行时会是尾调用吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16549827/
我创建了一个分支来开发新功能。由于这个新功能完全是作为一个新项目开发的,唯一可能的冲突来源是解决方案文件。 随着功能的开发,主分支更新了几次。当我完成开发和测试时,我做了: git checkout
我是一名优秀的程序员,十分优秀!