总计OCaml中的变量

时间:2015-12-08 19:40:05

标签: lambda functional-programming ocaml ml

我有一个循环字符串的程序,打印出每个字符的dir

我想将这些dir值合计为一个离散值,我可以打印出来。

这是我目前的代码:

let word = "(())";;

let dir = function
  | '(' -> 1
  | ')' -> -1
  | _ -> 0;;

let z =
  (String.iter (fun (c: char) ->
    let d = dir c in
      Printf.printf "%d is the direction of %c\n" d c
  ) word);;

目前,这打印出以下内容:

1 is the direction of (
1 is the direction of (
-1 is the direction of )
-1 is the direction of )

不是打印出来的,而是希望将4个值(1,1,-1,-1)相加并打印出来:

The overall direction is 0

我如何在OCaml中实现这一目标?

3 个答案:

答案 0 :(得分:1)

简短的回答是,您应该使用fold代替iter。由于标准字符串库中没有fold,您可能必须自己编写。

稍微长一点的答案是你可能想要编写一个递归函数来跟踪累积和作为其参数之一。

答案 1 :(得分:1)

OCaml中的循环以及其他函数式编程语言通常使用递归函数表示。这是一个可能的实现:

let count_parens str =
  let n = String.length str in
  let rec loop s i =
    if i < n then match str.[i] with
      | '(' -> loop (s + 1) (i + 1)
      | ')' -> loop (s - 1) (i + 1)
      | _ -> loop s (i + 1)
    else s in
  loop 0 0

或者,使用您的dir功能:

let count_parens str =
  let n = String.length str in
  let rec loop s i =
    if i < n then loop (s + dir str.[i]) (i + 1)
    else s in
  loop 0 0

循环的具体化是fold函数。不幸的是,OCaml标准库中没有String.fold函数。但是您可以使用Janestreet生成的Core标准库。使用fold函数,可以更简洁地表达此循环:

open Core_kernel.Std  

let count_parens str =
  String.fold str ~init:0 ~f:(fun s c -> s + dir c)

答案 2 :(得分:0)

使用参考:

let z =
  let counter = ref 0 in (String.iter (fun (c: char) ->
    counter := (!counter + dir c)
  ) word); !counter;;