在 OCaml 中总计一个变量
Totalling a variable in OCaml
我有一个循环遍历字符串并打印出每个字符的 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 中实现这一点?
简短的回答是您应该使用 fold
而不是 iter
。由于标准字符串库中没有 fold
,您可能需要自己编写。
稍微长一点的答案是,您可能想要编写一个递归函数来跟踪累积和作为其参数之一。
使用参考:
let z =
let counter = ref 0 in (String.iter (fun (c: char) ->
counter := (!counter + dir c)
) word); !counter;;
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)
我有一个循环遍历字符串并打印出每个字符的 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 中实现这一点?
简短的回答是您应该使用 fold
而不是 iter
。由于标准字符串库中没有 fold
,您可能需要自己编写。
稍微长一点的答案是,您可能想要编写一个递归函数来跟踪累积和作为其参数之一。
使用参考:
let z =
let counter = ref 0 in (String.iter (fun (c: char) ->
counter := (!counter + dir c)
) word); !counter;;
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)