我发现这种类型
zipper
和insert
函数定义如下:
type 'a zipper = 'a list * int;;
exception Empty
let empty = ([], 0)
let insert ((l, n): 'a zipper) (a: 'a) : 'a zipper =
let rec ins ll nn =
if nn = 0 then a::ll else
match ll with
| [] -> raise Empty
| h::q -> h::(ins q (nn-1))
in (ins l n, n)
我不明白的是这部分
in (ins l n, n)
。 ins
有两个参数,显然 ll
是一个列表,而 nn
是一个整数,但是为什么在调用 in (ins l n, n)
时我们这样调用它,一个 zipper
和一个整数?你能解释一下这是怎么回事吗?
让我们用一个更简单的函数
f
来尝试它,它从两个值构建一个元组:
# let f a b = (a,b)
val f : 'a -> 'b -> 'a * 'b = <fun>
如上为
f
编写对 ins
的调用时,我们有以下内容:
# (f 1 2, 3)
- : (int * int) * int = ((1, 2), 3)
所以
f 1 2
被分组为一个函数调用,产生 (1, 2)
,这个结果也在另一个元组中与 3
分组。
(ins l n, n)
等同于 let x = ins l n in (x, n)
或 ((ins l n), n)
.
不是多余的参数,逗号在这里其实是有作用的,就是构造一个左右两边值的元组