如何创建一个使用fold_right编码游程长度的函数?

时间:2015-09-27 02:18:02

标签: recursion functional-programming pattern-matching ocaml higher-order-functions

我创建了一个函数和辅助函数,用于查找列表中重复元素的数量以及这些元素的含义。

let rec _encode l x =
  match l with
  | [] -> 0
  | head::rest -> (if head = x then 1 else 0) + encode rest x

let encode l x = ((_encode l x), x)

在这种情况下,我必须指定要搜索的元素。

所以这是一个两部分的问题。 1)如何返回元组列表,格式为(int * 'a) list,其中int是rep的#,'a是重复的元素。

2)我如何使用fold_right实现这一点?

我正在思考以下几点:

let encode (l : 'a list) : (int * 'a) list = fold_right (fun (x,hd) lst -> 
    match x with 
    | [] -> 0
    | hd :: rest -> if hd x then (x+1, hd) else (x, hd)) l [] 

1 个答案:

答案 0 :(得分:1)

你的尝试看起来很混乱:

  • 它不使用lsthd(第一个)或rest
  • x用作列表(match x with [])和数字(x+1)。
  • x(列表)的元素是返回bools的函数? (... hd::rest -> ... if hd x
  • 该函数有时会返回一个数字(0),有时会返回一个元组((x, hd))。

我是这样做的:

let encode l =
    let f x = function
              | (n, y) :: zs when x = y -> (n + 1, y) :: zs
              | zs                      -> (1, x) :: zs
    in
    fold_right f l []

与以下内容相同:

let encode l =
    let f x z = match z with
                | (n, y) :: zs when x = y -> (n + 1, y) :: zs
                | zs                      -> (1, x) :: zs
    in
    fold_right f l []

与以下内容相同:

let encode l =
    fold_right (fun x z ->
        match z with
        | (n, y) :: zs when x = y -> (n + 1, y) :: zs
        | zs                      -> (1, x) :: zs
    ) l []