函数式编程中列表中通常的高阶原语是什么? (地图,折叠和?)

时间:2015-10-16 23:05:45

标签: functional-programming

您通常使用纯函数式编程中的列表做什么?

显然,我们map f [x0; x1; x2]会生成[f x0; f x1; f x2]fold f acc [x0; x1; x2],会产生f (f (f acc x0) x1) x2)

对于map,调用f之间不会传输任何信息;对于foldf生成的所有信息都会通过累加器acc在下一次调用中重新注入。

我还看到flatmap之类的内容会在map f返回列表时连接f生成的列表,而for_all将谓词应用于所有元素列表,但这些只是mapfold的特殊情况。

我可以考虑一些产生列表但在迭代期间保留累加器的中间件(OCaml语法):

let rec map_acc ~f acc = function
  | [] -> []
  | x::xs -> let (y, acc) = f x acc in y::(map_acc ~f acc xs)

问题:

  • map_acc函数式编程中的常用概念吗?
  • 如果是,那么它的规范名称是什么?
  • 是在标准库中实现的吗?
  • 其他常见的高阶函数是什么?

注意:

以下是使用map_acc生成运行总和的示例:

let sums xs = map_acc ~f:(fun x sum -> let sum = sum + x in (sum, sum)) 0 xs

sums [3; 5; 6; 9]生成[3; 8; 14; 23]。授予sums可以使用fold和精心设计的累加器来实现,但mac_acc更简单。

1 个答案:

答案 0 :(得分:2)

map_acc看起来更像一般scan_left

let scan_left f init list =
  let _, xs = List.fold_left
      (fun (acc, coll) elt ->
         let acc' = f acc elt in acc', acc'::coll)
      (init, []) list in
  List.rev xs

scan_left (+) 0 [3; 5; 6; 9] => [3; 8; 14; 23]

这个函数和变体在几种函数式语言的标准库中以各种名称出现,但不是OCaml。

这些函数都不值得被称为原语。