F#中断超载不起作用

时间:2016-06-27 16:55:13

标签: f#

let (->>>) lst exp = for i in lst do exp

let result = [0..5] ->>> ([1..5] ->>> printf "hi")
let result2 = for i in [0..5] do for x in [1..5] do printf "hi"

我期待resultresult2做同样的事情。但结果打印只需一次。但是,result2打印30次。这里缺少什么?

1 个答案:

答案 0 :(得分:9)

在您的运算符定义中,exp不一定是函数。您定义运算符的方式exp是任何值。例如,您可以这样做:

[0..1] ->>> 42

这会编译甚至运行,因为运算符定义中没有任何内容需要exp参数作为函数。或其他任何事情。

如果你想让exp在循环体内反复评估,你需要使它成为一个函数,并确保循环体调用它。由于您对此没有任何要求,因此最简单的要求是unit -> 'a。你不必真正声明它的类型,你可以让编译器从它的使用中推断它:

let (->>>) lst exp = for i in lst do exp()

注意exp之后的括号 - 它们表示类型unit的值,从而使表达式exp()成为函数应用程序(即函数exp应用于值{{1} }})。

当然,根据这个定义,您无法编写(),因为[1..5] ->>> printf "hi"不是函数。所以相反,你必须写:

printf "hi"

现在你打印出五个" hi"打印出来。

这是因为[1..5] ->>> (fun() -> printf "hi") 语法实际上是语言的一个特殊部分,而不是#34;只是另一个函数"在标准库中定义。使用聪明的函数或运算符定义,您无法真正创建相同的效果。

如果您想要构建比函数和运算符更复杂的语法,请查看computation expressions