在 OCaml 上实现一个保留累加器的函数
Implementing a function with keeping accumulator on OCaml
我写了一个给定列表中字符串长度的函数。例如,当用户输入 stringy ["a";"bbb";"cc";"ddddd"]
。它returns[("a",1); ("bbb",3); ("cc",2); ("ddddd",5)]
。我想用累加器做同样的功能。我怎样才能做到这一点 ?
let rec stringy lst =
match lst with
| [] -> []
| x::xs -> (x, String.length x) ::stringy xs ;;
实质是在处理输入列表时向收集答案的函数添加另一个参数。
这是一个将列表的每个元素乘以 2 的函数:
let rec double list =
match list with
| [] -> []
| h :: t -> (h * 2) :: double t
下面是带有累加器的相同函数:
let rec double_acc accum list =
match list with
| [] -> accum
| h :: t -> double_acc ((2 * h) :: accum) t
第二个版本有两个问题:(1) 它需要一个调用者不感兴趣的额外参数; (2) 它 return 是倒序的列表。您可以通过编写一个包装函数来解决这些问题,该函数添加额外的参数,然后使用 List.rev
.
反转结果
更新
包装函数只是调用另一个函数的函数,可能会调整参数和 return 值。
这是一个包装函数,通过包装cos来计算sin^2:
let wrap_sin2 theta =
let cos_theta = cos theta in
1.0 -. cos_theta *. cos_theta
对于上面的double_acc
,内部调用需要额外的[]
参数,结果需要使用List.rev
取反。我把它留给你去弄清楚如何处理你的实际问题,因为我怀疑这是一个家庭作业。
如果我使用累加器约束:
let stringy lst =
lst
|> List.fold_left (fun a s -> ((String.sub s 0 1),(String.length s) ) :: a ) []
|> List.rev
但是为什么要使用累加器?
另一种方式:
let stringy lst =
lst
|> List.map (fun s -> ((String.sub s 0 1),(String.length s) ) )
我写了一个给定列表中字符串长度的函数。例如,当用户输入 stringy ["a";"bbb";"cc";"ddddd"]
。它returns[("a",1); ("bbb",3); ("cc",2); ("ddddd",5)]
。我想用累加器做同样的功能。我怎样才能做到这一点 ?
let rec stringy lst =
match lst with
| [] -> []
| x::xs -> (x, String.length x) ::stringy xs ;;
实质是在处理输入列表时向收集答案的函数添加另一个参数。
这是一个将列表的每个元素乘以 2 的函数:
let rec double list =
match list with
| [] -> []
| h :: t -> (h * 2) :: double t
下面是带有累加器的相同函数:
let rec double_acc accum list =
match list with
| [] -> accum
| h :: t -> double_acc ((2 * h) :: accum) t
第二个版本有两个问题:(1) 它需要一个调用者不感兴趣的额外参数; (2) 它 return 是倒序的列表。您可以通过编写一个包装函数来解决这些问题,该函数添加额外的参数,然后使用 List.rev
.
更新
包装函数只是调用另一个函数的函数,可能会调整参数和 return 值。
这是一个包装函数,通过包装cos来计算sin^2:
let wrap_sin2 theta =
let cos_theta = cos theta in
1.0 -. cos_theta *. cos_theta
对于上面的double_acc
,内部调用需要额外的[]
参数,结果需要使用List.rev
取反。我把它留给你去弄清楚如何处理你的实际问题,因为我怀疑这是一个家庭作业。
如果我使用累加器约束:
let stringy lst =
lst
|> List.fold_left (fun a s -> ((String.sub s 0 1),(String.length s) ) :: a ) []
|> List.rev
但是为什么要使用累加器?
另一种方式:
let stringy lst =
lst
|> List.map (fun s -> ((String.sub s 0 1),(String.length s) ) )