applying a list to a function's arguments - list

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 |];;

Related

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.

Getting all indices of a value

Im trying to create a haskell function where all the indices of an occurence of a value in a list are returned as a list, so like
indices 3 [1,2,3,3,7]
gives [2, 3] as output. I am very new to Haskell and couldnt find something useful. I tried using filter, but all i got working is getting a list of [3, 3] but not the actual indices. It would be cool if you could give me a little hint.
This is a pretty common pattern in functional programming, sometimes called decorate-process-undecorate. The idea is that you want to attach some extra information to each of the elements in your list, filter using a slightly altered version of the filter you would have done normally, then strip that extra information away.
indicies n = undecorate . filter predicate . decorate where
decorate = ...
predicate = ...
undecodate = ...
When trying to code decorate I suggest taking a look at the function zip:
zip :: [a] -> [b] -> [(a, b)]
Consider its effect on infinite lists, too, such as repeat 1 or [1,3,...]. When trying to code undecorate you'll likely want to map:
map :: (a -> b) -> [a] -> [b]
Finally, don't worry about the efficiency of this process. In a strict language, decorate-filter-undecorate might require 3 traversals of the list. In a non-strict language like Haskell the compiler will automatically merge the 3 inner loops into a single one.

ocaml sum of two lists with different length

I tried to add two lists with different lengths using this:
let sumList(a,b) = match a,b with
|[],_ -> []
|(x::xs,y::ys)-> (x + y)::diffList(xs,ys)
It returns Unbound value sumList. Is it possible to do this as in Haskell: zipWith(+) a b.
Possibly the actual error is "Unbound value diffList", since you don't define diffList in your code.
If this is a transcription error, then the next problem is that you need to declare sumList as a recursive function: let rec sumList (a, b) = ....
Your pattern match is not exhaustive. It fails if the first list is longer.
The Haskell zipWith is friendlier than the OCaml List.map2, which requires the lists to be the same length. I don't think there's anything so friendly in the OCaml standard library.

Flattening a list of lists in OCaml

I am implementing this hoemwork functionality using Ocaml:
Not allowed to use List module
the function has type 'a list list -> 'a list
the function return a list consisting of the lists in x concatenated together (just top level of lists is concatenated, unlike List.flatten)
For example : [[1,2,3],[45]] => [1,2,3,4,5] and [[[1,2,3],[4,5]],[[6,7]]] => [[1,2,3],[4,5],[6,7]]
I am not sure where to start, can anyone give me some suggestion? Thank you
I don't see the difference between List.flatten and your function.
To answer to your question: as usual with lists, try to think about the base cases:
what do you do when you concatenate an empty list with something ?
what do you do when you concatenate a non-empty list (with a head and a tail) with something ?
Wrap everything into a pattern match, cook it for few hours, and that's done :-)
Thomas has given excellent advice. Your basic operation is going to be to append one list to another. It might help to write this function as a separate function first. It will look something like this:
let rec myappend a b =
match a with
| [] -> (* Empty list prefixed to b (easy case) *)
| ahead :: atail -> (* Recursive case *)
Armed with your own append function, you can carry out another level of recursion
to append all the top-level lists as Thomas suggests.

Ocaml modules implementation

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.