Module List.sum在核心中,don';我不懂集装箱

Module List.sum在核心中,don';我不懂集装箱,module,ocaml,ocaml-core,Module,Ocaml,Ocaml Core,我试图理解Jane streets core的List.sum。我让它工作在一个简单的整数列表上,但不理解Core容器的概念,并且找到了api文档,以便于理解。下面是一些有效的代码: #require "core";; open Core;; List.sum (module Int) [1;2;3] ~f:ident;; - : int = 6 #show List.sum;; val sum : (module Base__.Container_intf.Summable with

我试图理解Jane streets core的
List.sum
。我让它工作在一个简单的整数列表上,但不理解Core容器的概念,并且找到了api文档,以便于理解。下面是一些有效的代码:

#require "core";;
open Core;;
List.sum (module Int) [1;2;3] ~f:ident;;
- : int = 6


#show List.sum;;

val sum :
  (module Base__.Container_intf.Summable with type t = 'sum) ->
  'a list -> f:('a -> 'sum) -> 'sum

为什么我必须使用
模块Int
和标识功能<代码>[1;2;3]已经提供了一种类型的
int list
。关于Core背后的设计思想有什么好的信息吗?

该模块提供了将所讨论的值相加的方法。
f
提供了从列表中的元素类型到要求和的元素类型的转换函数

如果您只想对列表中的整数求和,那么所需的求和函数在
Int
模块中(因此我们需要
moduleint
),而转换函数只是
ident
(因为我们根本不需要转换值)

但是,如果您希望获得整数的和,但从表示整数的字符串列表开始,该怎么办?那我们就可以了

utop#List.sum(模块Int)[“1”;“2”;“3”;“4”];;
-:f:(字符串->整数)->整数=
i、 例如,如果我们想在字符串列表上使用
模块Int
求和,那么我们首先需要一个函数,该函数将
string
类型的每个值转换为
Int
类型的值。因此:

utop#List.sum(模块Int)[“1”;“2”;“3”;“4”]~f:Int.of_string;;
-:int=10
这是相当冗长的,但它给了我们很大的灵活性!想象一下,尝试使用不同的交换运算求和,可能是在记录中的特定字段上

但是,这不是OCaml中对整数列表求和的惯用方法
List.sum
List
模块“继承”的一个特定函数,因为它满足
Base
库设计中使用的a容器接口(它提供了
核心
的基本功能。该功能使用起来比较复杂的原因是,它是对代数结构(在这种情况下,是对元素集合的高度通用化设计的结果,这些元素集合可以在定义了交换操作的元素中进行转换)

对于普通的整数求和,Ocamler只需使用一个简单的折叠:

utop#List.fold[1;2;3;4]~init:0~f:(+);;
-:int=10

了解
核心
背后的设计决策的一个好地方是。另一个好资源是。您也可以咨询
基础
repo(),或者在

Janestreet的图书馆对新来者来说是出了名的不透明,但它们正在变得更好,社区将乐于帮助你学习


虽然文档很简洁,但表达力很强。特别是,它倾向于依靠类型来承载大部分重量,这意味着代码基本上是自文档化的。学习阅读好类型需要一些练习,但这是非常值得的,imo,并且有它自己的回报!

我对Core不是特别熟悉,但OCaml不支持函数和运算符重载(特殊多态性),而一个完全多态的加法运算符不会非常安全或快速。因此,您需要指定加法函数,通过向它传递一个符合
Summable
模块签名的模块来实现,而
Int
大概就是这样。函数参数可能只是为了支持输入元素的转换,li例如,访问特定的记录字段。