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"
我期待result
和result2
做同样的事情。但结果打印只需一次。但是,result2
打印30次。这里缺少什么?
答案 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。