I'm trying to understand List.sum from Jane streets core. I got it to work on a simple list of integers, but don't understand the concepts of Core's containers, and find the api documentation to terse to understand. Here's some code that works:
#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
Why do I have to use module Int and the identity function. [1;2;3] already provides a type of int list. Is there any good information about the design ideas behind Core?
The module provides the means of summing the values in question. The
fprovides a transformation function from the type of elements in the list to the type of elements you want to sum.If all you want want to do is sum the integers in a list, then the summation function desired is in the
Intmodule (thus we needmodule Int) and the transformation function is justident(because we needn't transform the values at all).However, what if you wanted obtain a sum of integers, but starting with a list of strings representing integers? Then we would have
i.e., if we want to sum using the
module Intover a list of strings, then we'll first need a function that will convert each value of typestringto a value of typeint. Thus:This is pretty verbose, but it gives us a lot of flexibility! Imagine trying to sum using a different commutative operation, perhaps over a particular field in a record.
However, this is not the idiomatic way to sum a list of integers in OCaml.
List.sumis a specific function which theListmodule "inherits" by virtue of it satisfying the a container interface used in the library design ofBase(which provides the basic functionality ofCore. The reason this function is relatively complex to use is because it is the result of a highly generalized design over algebraic structures (in this case, over collections of elements which can be transformed in elements which have a commutative operation defined over them).For mundane integer summation, OCamlers just use a simple fold:
One good place to look for some insight into the design decisions behind
Coreis https://dev.realworldocaml.org/ . Another good resource is the Janestreet tech blog. You might also consult theBaserepo (https://github.com/janestreet/base) or post a question asking for more specific details on the design philosophy in https://discuss.ocaml.org/Janestreet's libraries have been notoriously opaque to newcomers, but they are getting a lot better, and the community will be happy to help you learn.
Tho the documentation is terse, it is very expressive. In particular, it tends to rely on the types to carry much of the weight, which means the code is largely self-documenting. It takes some practice to learn to read the types well, but this is well worth the effort, imo, and carries its own rewards!