Functional programming 标准ML:简化递归调用

Functional programming 标准ML:简化递归调用,functional-programming,sml,Functional Programming,Sml,我的书对索引遍历有以下定义(它在列表中以索引顺序计算树元素的列表): fun trav Empty = [] | trav(Node(t_1, x, t_2)) = trav t_1 @ (x::trav t_2); 简化第二行调用的约定/标准是什么(即,trav t_1和x::trav t_2)?我知道我在使用@操作符之前简化了这两个调用,但我想知道第一个trav调用是否在另一个调用之前完全求值,反之亦然(不太可能),或两者同时进行 谢谢 b外行你的直觉是正确的,trav t_1在函

我的书对索引遍历有以下定义(它在列表中以索引顺序计算树元素的列表):

fun trav Empty = []
    | trav(Node(t_1, x, t_2)) = trav t_1 @ (x::trav t_2);
简化第二行调用的约定/标准是什么(即,
trav t_1
x::trav t_2
)?我知道我在使用
@
操作符之前简化了这两个调用,但我想知道第一个
trav
调用是否在另一个调用之前完全求值,反之亦然(不太可能),或两者同时进行

谢谢


b外行

你的直觉是正确的,
trav t_1
在函数参数按从左到右的顺序求值时首先得到求值。这似乎有点奇怪,因为
@
是一个中缀运算符,但是
[1,2,3]@[4,5,6]
实际上可以重写为
(op@)([1,2,3],[4,5,6])
。您可以通过执行以下操作来验证
@
是否首先计算其左参数:

Standard ML of New Jersey v110.78 [built: Sun Jun  7 20:21:33 2015]
- (print "test1\n"; [1, 2, 3]) @ (print "test2\n"; [4, 5, 6]);
test1
test2
val it = [1,2,3,4,5,6] : int list
- 
基本上,您所拥有的相当于:

fun trav Empty = []
  | trav(Node(t_1, x, t_2)) = 
     let val l = trav t_1 
         val r = trav t_2
     in l @ (x::r) end