Ocaml modules implementation - ocaml

Ocaml's standard library contains various modules: List, Map, Nativeint, etc. I know that interfaces for these modules are provided (e.g. for the List module), but I am interested in the algorithms and their implementations used in modules' functions.
Where can I find that?

On your system: /usr/lib/ocaml/list.ml and other .ml files
On the web: https://github.com/ocaml/ocaml/blob/trunk/stdlib/list.ml and other .ml files in https://github.com/ocaml/ocaml/tree/trunk/stdlib
The List implementation is interesting to study. For example, the map function could be implemented like this:
let rec map f = function
| [] -> []
| a::l -> f a :: map f l
but is instead implemented like this:
let rec map f = function
| [] -> []
| a::l -> let r = f a in r :: map f l
What's the difference? Execute this:
List.map print_int [1;2;3] ;;
map print_int [1;2;3] ;;
The first one prints 123, but the second one prints 321! Since the evaluation of f a could produce side effects, it's important to force the correct order. This is what the official map implementation does. Indeed, the evaluation order of arguments is unspecified in OCaml even if all implementations follow the same order.
See also the Optimizing List.map post on the Jane Street blog for considerations on performance (List.map is efficient on small lists).

You can find the definitions in the OCaml source code. For example, implementation of the Map functions is in stdlib/map.ml in the OCaml source distribution.

They should already be installed on your system. Most likely (assuming a Unix system) they are located in /usr/lib/ocaml or /usr/local/lib/ocaml. Just open any of the .ml files.

Related

How to run Ocaml simulations

If I want to run a simulation of the abstract machine on the code below, how do I know what would be in the workspace, stack, and heap?
let rec map (f: 'a -> 'b) (y: 'a list): 'b list =
begin match y with
| [] -> []
| h :: t -> (f h) :: (map f t)
end in
let x = map (fun t -> t + 1) [0; 1; 2] in
0 :: x
You're using terminology that we (people reading StackOverflow) don't share. In particular, we don't know what abstract machine you're talking about.
Speaking very generally about computer systems, the workspace usually contains the current definitions. At the beginning it might contain predefined functions and so on. Your code uses some predefined type names (like 'a list) and constructors (like ::). I don't know if they need to be in your workspace specifically.
Very possibly your definitions of map and x would need to be loaded into the workspace as the first step.
The stack contains a record of the functions that have been called but haven't returned. In general it will be empty when you start an evaluation.
The heap is a general term for the set of values that exist at the moment but might disappear later (when no longer needed). Unless you count your values named map and x, the heap could also be empty at the beginning.
Sorry I can't be more specific. It sounds like you're taking a class, and you might want to consult some of the class resources (including the professor or TA :-)

How does this nested fold_left work? and what is ~f: and ~init:?

I have this code snippet in Ocaml which is taken from here. I know it fills a data structure for a demand (traffic matrix) with a the specified value and when the two hosts are the same it just fill the value with 0. In python or in any imerative language, we would use two for loop one inside another to do the task. I assume this is the reason we have two (fold_left) in this code in which each one is equivilant to a one for loop (I might be mistaken!). My question is how this code works? and what is ~f: and ~init:? are these labels. If they are labels why the compiler complains when I remove them or when I change them? even when I put these arguments in the right order?!
I have finished one book and have watched alot of youtube videos but still find it difficult to understand most of Ocaml code.
let create_3cycle_input () =
let topo = Net.Parse.from_dotfile "./data/topologies/3cycle.dot" in
let hosts = get_hosts topo in
let demands =
List.fold_left
hosts
~init:SrcDstMap.empty
~f:(fun acc u ->
List.fold_left
hosts
~init:acc
~f:(fun acc v ->
let r = if u = v then 0.0 else 53. in
SrcDstMap.set acc ~key:(u,v) ~data:r)) in
(hosts,topo,demands);;
Please, read my another SO answer that explains how fold_left works. Once you understand how a single fold works, we can move forward to the nested case (as well as to the labels).
When you have a collection of collections, i.e., when an element of a collection is another collection by itself, and you want to iterate over each element of those inner collections than you need to nest your folds. A good example, are matrices which could be seen as collections of vectors, where vectors are by themselves are also collections.
The iteration algorithm is simple,
state := init
for each inner-collection in outer-collection do
for each element in inner-collection do
state := user-function(state, element)
done
done
Or, the same in OCaml (using the Core version of the fold)
let fold_list_of_lists outer ~init ~f =
List.fold outer ~init ~f:(fun state inner ->
List.fold inner ~init:state ~f:(fun state elt ->
f state elt)
This function will have type 'a list list -> init:'b -> f:('b -> 'a -> 'b) -> 'b
and will be applicable to any list of lists.
Concerning the labels and their removal. The labels are keyworded arguments and enable passing arguments to a function in an arbitrary manner, which is very useful when you have so many arguments. Removing labels is sometimes possible, but could be disabled using a compiler option. And the Core library (which is used by the project that you have referenced) is disabling removing the labels, probably for the good sake.
In general, labels could be omitted if the application is total, i.e., when the returned value is not a function by itself. Since fold_left returns a type variable, it could always be a function, therefore we always need to use labels with the Core's List.fold (and List.fold_left) function.

List Comprehension in Ocaml?

It seems that Ocaml batteries have comprehension syntax:
http://en.wikipedia.org/wiki/List_comprehension#OCaml
However, what module should I include to use this syntax? I already open Batteries, but it doesn't work. Or is there a more idiomatic way to do list comprehension? I can use List.map and BatList.remove_if to achieve similar results, but that is much less elegant.
Currently there're two libraries in OCaml that provide list comprehension, one was formerly a part of OCaml Batteries, another is shipped with camlp4. Neither is widely used and I, personally, do no recommend you to use any.
For list comprehension to work, you need to change the syntax of the language. This can be done with preprocessing your program, written in an extended syntax, with a camlp4 preprocessor. Also, list comprehension is not a first class citizen in OCaml community, and it is not well supported by the modern toolkits. Although, you can still easily play with it in a toplevel, for that you need, to install the list comprehension package:
opam install pa_comprehension
and load it into a toplevel, using the following directives:
# #use "topfind";;
# #camlp4o;;
# #require "pa_comprehension";;
# open Batteries;;
# [? 2 * x | x <- 0 -- max_int ; x * x > 3 ?];;
But again, my personal opinion that list comprehension is not the best way to structure your code.
Life without comprehension
The example, you provided, can be expressed using core_kernel Sequence module (an analog of the Batteries Enum)
let f n =
Sequence.(range 0 n |>
filter ~f:(fun x -> x * x > 3) |>
map ~f:(fun x -> x * 2))
Hence a filter |> map is such a common idiom there exists a filter_map function:
let f n =
Sequence.(range 0 n |>
filter_map ~f:(fun x ->
if x * x > 3 then Some (x * 2) else None))
You may notice, that this examples takes more code, than list comprehension. But as soon as your programs will start to mature from simple hello world applications with integers to something more sophisticated, you will agree that using explicit iterators is more readable and comprehensible.
Also, since libraries in Core are so consistent, you can use a simple List instead of Sequence just by substituting the latter by the former. But of course, List is eager, unlike the Sequence, so playing with max_int using lists is not a good idea.
Moreover, since all containers are monads, you can use monadic operators for mapping, like:
let odds n = List.(range 0 n >>| fun x -> x * 2 + 1)
list comprehension is already included in standard ocaml
#require "camlp4.listcomprehension";;
[ x * x | x <- [ 1;2;3;4;5] ];;
- : int list = [1; 4; 9; 16; 25]

applying a list to a function's arguments

How to write a function in F# for applying a list of values to a function like the Apply (##) symbol in mathematica (map elements of the list to function arguments)
for example apply f [1;2;3] calls f(1,2,3) or as in curried function application f 1 2 3
You can write a function like apply that takes any F# function and an array of arguments and invokes the function via Reflection.
However, there is a good reason why this is not in the standard F# library - one of the strengths of F# (compared e.g. to Mathematica) is that it is statically typed language and can catch most potential errors at compile time. If you use something like apply then you'll lose this checking [because you never know if the list has the right length].
Nevertheless, here is an example of how to do this:
open Microsoft.FSharp.Reflection
let apply (f:obj) (args:obj[]) =
if FSharpType.IsFunction(f.GetType()) then
let invoke =
f.GetType().GetMethods()
|> Seq.find (fun mi -> mi.Name = "Invoke" && mi.GetParameters().Length = args.Length)
invoke.Invoke(f, args)
else failwith "Not a function"
Sample use looks like this:
let add a b = a + b;;
apply add [| 3;4 |];;

Applying a function with multiple inputs using Map? (Haskell)

G'day guys,
Trying currently to finish up a bit of homework I'm working on, and having an issue where I'm trying to apply map across a function that accepts multiple inputs.
so in the case I'm using processList f (x:xs) = map accelerateList f xs x xs
processList is given a floating value (f) and a List that it sorts into another List
Accelerate List takes a floating value (f) a List and a List Object through which it returns another List Object
I know my Accelerate List code is correct, but I cannot for the life of me get the syntax for this code working:
processList :: Float -> [Object] -> [Object]
accelerate f [] = []
accelerate f [x] = [(accelerateForce f x x)]
accelerate f (x:xs) = map accelerateList f xs x xs
Any ideas? I've been scratching my head for about 3 hours now. I know it's something really simple.
First of you will probably want to use some parenthesis here:
map accelerateList f xs x xs
The function map takes exactly two arguments (not five), so you should do something like this for example:
map (accelerateList f xs x) xs
But on the other hand, that doesn't fit with your function signatures. The problem is probably that you haven't structured your solution in a good enough way. Might be a separate question, but explaining what you're trying to accomplish with the accelerate-function (or which ever one is the "top" one) would certainly help.