给定一个拉链:
type 'a zipper = 'a list * int;;
exception Empty
let empty = ([], 0)
给出的删除操作是:
let remove_exn (l,n) =
let rec rem ll nn = match (nn,ll) with
| (0,h::q) -> (h,q) | (_,[]) -> raise Empty
| (_,h::q) -> let (x,xs) = rem q (nn-1) in (x,h::xs)
in (rem l n,n-1)
因为我不喜欢本地功能,并且在我之前问题的答案的帮助下。我这样做了:
let cons_rem x (lz : 'a zipper option) : 'a zipper option =
match lz with
| Some (l, n) -> Some (x::l,n+1)
| None -> None
let rec remove ((l, n): 'a zipper) : 'a zipper option =
match (l, n) with
| (h::t, n) when n = 0 -> Some (t, n-1)
| (h::t, n) when n > 0 -> cons_rem h (remove (t, n-1))
| (_, n) -> None;;
let remove_exn (lz: 'a zipper option) =
match lz with
| None -> raise Empty
| Some lz -> lz;;
从概念上讲,如果我们有这个拉链
([1;2;3], 1)
并且我们想要移除,那么它会输出到 ([1; 3], 0)
上面的代码吗?此外,给出的解决方案不会产生拉链,它会产生其他东西,但文档说它会产生拉链,但此输入的第一个解决方案的输出是:([1;2;3], 1)
is (int * int list) * int = ((2, [1; 3]), 0)
which is not a zipper , 但我的版本产生了拉链,第一个解决方案不正确吗?