How to use list comprenhension in Ocaml - list

This code is in Haskell. How can i do the same thing in OCAML?
perfect n = [x | x<-[1..n], sum(f x) == x]
f x = [i | i<-[1..x-1], x `mod` i ==0]

While Jeffrey's answer is correct, using appropriate libraries (in this case, sequence), you can get something that is similar in terseness and semantics to the Haskell style:
module S = Sequence
let sum = S.fold (+) 0
let f x = S.filter (fun i -> x mod i = 0) S.(1 -- (x-1))
let perfect n = S.filter (fun x -> sum (f x) = x) S.(1 -- n)

You're using many (really nice) features of Haskell that don't exist in OCaml.
For list comprehensions, you can use List.filter.
For the notation [x .. y] you can use this range function:
let range a b =
let rec go accum i =
if i > b then List.rev accum else go (i :: accum) (i + 1)
in
go [] a
For sum you can use this:
let sum = List.fold_left (+) 0

Related

Operation substitution in OCaml

I have one task in hand that I am 90% done with it but just don't quite know how to finish it. So the task is as follows : " Write a non-recursive function which takes a function, and two lists as an input, and returns a third list which contains the result of the function applied on all possible pairs of elements from both input lists." So I have to get it as below.
# cart_fun ( * ) [1;2;2;6;3;9;1] [2;3];; -: int list = [2; 3; 4; 6; 4; 6; 12; 18; 6; 9; 18; 27; 2; 3]
My struggle is that I don't know how to make a function substitution. Here is my code.
let cart_fun list1 list2 =
let res = List.fold_left (fun acc x -> List.fold_left (fun acc y -> (x * y) :: acc) acc list2) [] list1
in List.rev res;;
But I would like that in part (x*y) the multiplication be given as an argument before the lists.
Thank you for your help in advance.
Most of the journey has already been made! Well done!
As you can see by using the fold_left function, in OCaml (as in other functional languages) you can pass functions as arguments (and even return them), which is why you can provide fold_left with an accumulation function. Here is your code:
let cart_fun list1 list2 =
let res = List.fold_left (fun acc x ->
List.fold_left (fun acc y -> (x * y) :: acc) acc list2)
[] list1
in List.rev res;;
Even if the code is very good, let's rephrase it a bit to see it more clearly!
let cart_fun list1 list2 =
let process_list_2 fst_acc =
List.fold_left
(fun snd_acc y -> (x * y) :: snd_acc)
fst_acc
list2
in
let result = List.fold_left (fun acc x -> process_list_2 acc x) [] list1 in
List.rev result
As you may have realised: (fun acc x -> process_list_2 acc x) is, in fact, identical to process_list_2 so, let's rephase one more time:
let cart_fun list1 list2 =
let process_list_2 fst_acc =
List.fold_left
(fun snd_acc y -> (x * y) :: snd_acc)
fst_acc
list2
in
let result = List.fold_left process_list_2 [] list1 in
List.rev result
But hey, we want to generalise cart_fun in ordrer to have, instead of cart_fun list1 list2, we want cart_fun modifier list1 list2, where modifier is just a function... So, no problem, let's changing this part of the code:
let cart_fun modifier list1 list2 =
let process_list_2 fst_acc =
List.fold_left
(fun snd_acc y -> (modifier x y) :: snd_acc)
fst_acc
list2
in
let result = List.fold_left process_list_2 [] list1 in
List.rev result
And voila! As you can see, there wasn't much modification required. Just keep in mind that in OCaml, you can consider that a variable will contain a function; which is pretty cool!
Btw, the "general behaviour" that you want to capture looks a lot like what we call "a comprehension" (like in Python and Haskell). And since OCaml 4.10, there is a function in list module which allow you to write easily comprehension : List.concat_map val concat_map : ('a -> 'b list) -> 'a list -> 'b list which has the same effect than mapping over a list of 'a, producing a list of list of b and flatten the list into a list of b.
So you can see your cartesian product as :
let cart_fun modifier list1 list2 =
List.concat_map (fun x ->
List.concat_map (fun y ->
[modifier x y]
) list2
) list1
But as you can see... it's not much more readable than before! Fortunately, in addition to passing functions as arguments, OCaml also allows you to describe your own operators. For example, here we could describe an operator to simplify the chaining of concat_map which we would randomely call... >>= :
let (>>=) list f = List.concat_map f list
let cart_fun modifier list1 list2 =
list1 >>= fun x ->
list2 >>= fun y -> [modifier x y]
Awesome, can we go deeper in the readability ? Of course, since OCaml 4.08, you can define let operators. So defining your own let with a suffix. For example, here, let's define let* (which will be exactly the same of >>=)
let (let*) list f = List.concat_map f list
(* So `let* x = l in g x` is the same of `l >>= fun x -> g x` *)
nice no?
And now, we can rewrite our example:
let cart_fun modifier list1 list2 =
let* x = list1 in
let* y = list2 in
[modifier x y]
And voila ! Even:
let cart_fun modifier list1 list2 =
let process_list_2 fst_acc =
List.fold_left
(fun snd_acc y -> (modifier x y) :: snd_acc)
fst_acc
list2
in
let result = List.fold_left process_list_2 [] list1 in
List.rev result
Is "more direct" I think it is nice to see how OCaml is expressive!

Square numbers in list and then add them up

I am trying to create a function that squares the numbers of an ML list and then adds those numbers up
fun sqsum(lst) = map (fn x => x*x) lst;
What I have there takes a list and returns a list of the square of each number but I can't figure out the adding part.
You could solve one sub-problem at a time and compose the result:
val sq = map (fn x => x*x)
val sum = foldl (fn (x, result) => x + result) 0
val sqsum = sum o sq
Or you could fuse the map and the foldl together:
val sqsum = foldl (fn (x, result) => x*x + result) 0
Or you could write this function with a recursive definition:
fun sqsum (x::xs) = x*x + sqsum xs
| sqsum [] = 0
And eventually improve it to be tail-recursive:
fun sqsum L =
let fun f (x::xs) result = f xs (x*x + result)
| f [] result = result
in f L 0 end
Even though higher-order list combinators like map and foldl are immensely useful and improve the readability of code once you get used to them, solving introductory exercises using manual recursion is very valuable to the learning process; after all, map and foldl are built this way.

Core's `List.init` in Pervasives?

I'm used to JaneStreet's Core library. Its List module has a neat init function:
List.init;;
- : int -> f:(int -> 'a) -> 'a list = <fun>
It allows you to create a list with using a custom function to initialize elements:
List.init 5 ~f:(Fn.id);;
- : int list = [0; 1; 2; 3; 4]
List.init 5 ~f:(Int.to_string);;
- : string list = ["0"; "1"; "2"; "3"; "4"]
However, this function doesn't seem to exist in Pervasives, which is sad. Am I missing something, or do I have to implement it myself? And if I do need to write it, how do I achieve this?
EDIT:
I have written an imperative version of init, but it doesn't feel right to have to resort to OCaml's imperative features in such a case. :(
let init n ~f =
let i = ref 0 in
let l = ref [] in
while !i < n do
l := (f !i) :: !l;
incr i;
done;
List.rev !l
;;
EDIT 2:
I've opened a pull request on OCaml's GitHub to have this feature included.
EDIT 3:
The feature was released in OCaml 4.06.
A recursive implementation is fairly straightforward. However, it is not tail-recursive, which means that you'll risk a stack overflow for large lists:
let init_list n ~f =
let rec init_list' i n f =
if i >= n then []
else (f i) :: (init_list' (i+1) n f)
in init_list' 0 n f
We can transform it into a tail-recursive version using the usual techniques:
let init_list n ~f =
let rec init_list' acc i n f =
if i >= n then acc
else init_list' ((f i) :: acc) (i+1) n f
in List.rev (init_list' [] 0 n f)
This uses an accumulator and also needs to reverse the intermediate result, as the list is constructed in reverse. Note that we could also use f (n-i-1) instead of f i to avoid reversing the list, but this may lead to unexpected behavior if f has side-effects.
An alternative and shorter solution is to simply use Array.init as a starting point:
let init_list n ~f = Array.(init n f |> to_list)
You can copy the code from JaneStreet and use it.
The code look's like (but not exactly the same) :
let init n ~f =
if n < 0 then raise (Invalid_argument "init");
let rec loop i accum =
if i = 0 then accum
else loop (i-1) (f (i-1) :: accum)
in
loop n []
;;
You can find the original code inside core_list0.ml from the package core_kernel.

how to rewrite code using tail recursion

I just looking for a little advice, how to rewrite code using tail recursion
open Core.Std;;
let rec dig x =
match x with
| 0 -> []
| _ -> x :: dig (x - 1)
;;
let () =
let numbers = dig 10 in
List.iter ~f:(Printf.printf "%d, ") numbers;
Printf.printf "\n";
;;
Any advice will be helpful
let dig x =
let rec f x s =
match x with
| 0 -> s
| _ -> f (x-1) (x::s)
f x []
Is this what you want? It's using tail recursion.
Edit:
for a decreasing seq, just replace (x::s) with (List.append s [x]) or (s # [x]) but it's NOT a good idea,and List.rev is better:
let dig x =
let rec f x s =
match x with
| 0 -> s
| _ -> f (x-1) (s # [x])
f x []
let dig x =
let rec f s z =
if z = x then s
else f (z::s) (z+1)
in
f [] 0
not sure if this floats your boat: You may have to tweak the border cases depending if you want 0 or the starting number included.
If you don't want to use List.rev after building the list backwards (which in my opinion is perfectly fine), nor starting your recursion with 0 instead of n, you can use some kind of continuation:
let dig2 x =
let rec aux x kont =
match x with
| 0 -> kont
| _ -> aux (x-1) (fun l -> kont (x::l))
in
aux x (fun l -> l) [];;
Basically each step returns a function that, given the list built by the remaining steps, will append x to it. We start the recursion with the identity function since we don't have anything to build yet. Then, when we exit from the recursion, we thus just have to apply the empty list to the obtained function.
Well, it seems to can have multiple solutions
open Core.Std;;
let rec digtail ?(l=[]) x =
match x with
| 0 -> l
| _ -> digtail ~l: (l # [x]) (x - 1)
;;
let () =
let numbers = digtail 10 in
List.iter ~f:(Printf.printf "%d, ") numbers;
Printf.printf "\n";
;;
Thanks to all, you helped a lot.

How to recursively multiply all elements of a list with itself to create a matrix? OCaml

I need to create a weight matrix essentially by multiplying all the elements of a list with themselves.
for example if my list is [1;-1;1;-1], the resulting matrix would be
[[0;-1;1;-1],
[-1;0;-1;1],
[1;-1;0;-1],
[-1;1;-1;0]]
(diagonal is filled with 0's because a node shouldn't be able to lead to itself)
This would be a piece of cake, but it has to be done recursively, with the following constraints:
only List.hd, List.tl and List.nth can be used, and as a parameter, I can only pass in the list:
let rec listMatrix = fun(myList)->...
Is there any way to do this? Or should I just try to find some fundamentally different way to solve this problem?
Also, only functional approach is allowed, no global variables.
One way to do it recursively is as follows:
let l = [1;-1;1;-1];;
let rec index xs =
let idx xs i = match xs with
[] -> []
| (x::xss) -> (i,x) :: idx xss (i+1)
in idx xs 0
fst (x,y) = x
snd (x,y) = y
let rec mult xs ys = match xs with
[] -> []
| (x::xss) -> (List.map (fun y->if (fst x == fst y) then 0 else (snd y*snd x)) ys) :: (mult xss ys)
let mult0 xs = mult (index xs) (index xs)
What the code does is, as asked, multiplying a vector with itself. The vector is indexed with numbers in order to handle diagonal elements specially.
The output is:
# mult0 l;;
- : int list list =
[[0; -1; 1; -1]; [-1; 0; -1; 1]; [1; -1; 0; -1]; [-1; 1; -1; 0]]