Zipper数据结构删除操作,[关闭]

问题描述 投票:0回答:0

给定一个拉链:

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 , 但我的版本产生了拉链,第一个解决方案不正确吗?

functional-programming ocaml
© www.soinside.com 2019 - 2024. All rights reserved.