The execution of lazy evaluation (OCaml) - functional-programming

I am trying to under the execution of lazy evaluation.
I created a lazy list type and according map function.
type 'a zlist = 'a node_t lazy_t
and 'a node_t = Empty | Node of 'a * 'a zlist
let rec zlist_of_list l = lazy (
match l with
| [] -> Empty
| hd::tl -> Printf.printf "transforming %d\n" hd;Node (hd, zlist_of_list tl)
)
let rec list_of_zlist zl =
match Lazy.force zl with
| Empty -> []
| Node (hd, tl) -> hd::(list_of_zlist tl)
let rec map_z f zl = lazy (
match Lazy.force zl with
| Empty -> Empty
| Node (hd, tl) -> Node (f hd, map_z f tl)
)
First question:
From my understanding, lazy just encapsulate things inside () behind without immediate execution.
So for function zlist_of_list, the whole
match l with
| [] -> Empty
| hd::tl -> Node (hd, zlist_of_list tl)
Will be delayed, not a single bit is executed when zlist_of_list is applied, so does map_z.
Am I right?
Below, I try to do double lazy map
let f1 x = Printf.printf "%d\n" x; x
let f2 x = Printf.printf " %d\n" (-x); (-x)
let zl = zlist_of_list [1;2;3]
let zl_m2 = map_z f2 (map_z f1 zl)
let _ = list_of_zlist zl_m2
The outcome is
transforming 1
1
-1
transforming 2
2
-2
transforming 3
3
-3
The I don't understand. It seems the execution is by column, not by row. I thought it should be
Every element is transformed first
Then f1 is mapped to every element
The f2 is mapped to every element
Second question:
Why via lazy, the execution order becomes like that?

To your first question: that's right, map_z will return a thunk that calculates the next part of the list, not the list itself. In particular, the recursive call within the definition of map_z will not descend into the rest of the list until it is forced - you can take one transformed element from the result of a map_z without calculating the rest.
This is also the answer to your second question: the reason you see one element being transformed, then passed to f1, then f2 is that at each step you are taking one element from a lazy list and the others remain suspended.
And that's the whole point of lazy lists! Doing things that way is useful because it provides a fairly natural way to program with infinite (or very large) lists. If an entire list had to be calculated first before using the elements, it would not really be a lazy data structure.

Related

F# adding lists

How would I go about adding sub-lists.
For example, [ [10;2;10]; [10;50;10]] ----> [20;52;20] that is 10+10, 2+50 and 10+10. Not sure how to start this.
Fold is a higher order function:
let input = [[10;2;10]; [10;50;10]]
input |> Seq.fold (fun acc elem -> acc + (List.nth elem 1)) 0
val it : int = 52
Solution 1: Recursive version
We need a helper function to add two lists by summing elements one-to-one. It is recursive and assumes that both lists are of the same length:
let rec sum2Lists (l1:List<int>) (l2:List<int>) =
match (l1,l2) with
| ([],[]) -> []
| (x1::t1, x2::t2) -> (x1+x2)::sum2Lists t1 t2
Then the following recursive function can process a list of lists, using our helper function :
let rec sumLists xs =
match xs with
| [] -> [] // empty list
| x1::[] -> x1 // a single sublist
| xh::xt -> sum2Lists xh (sumLists xt) // add the head to recursion on tail
let myres = sumLists mylist
Solution 2: higher order function
Our helper function can be simplified, using List.map2:
let sum2hfLists (l1:List<int>) (l2:List<int>) = List.map2 (+) l1 l2
We can then use List.fold to create an on the flow accumulator using our helper function:
let sumhfList (l:List<List<int>>) =
match l with
| [] -> [] // empty list of sublist
| h::[] -> h // list with a single sublist
| h::t -> List.fold (fun a x -> sum2hfLists a x) h t
The last match case is applied only for lists of at least two sublists. The trick is to take the first sublist as starting point of the accumulator, and let fold execute on the rest of the list.

how to get the Column of a matrix in Ocaml

I want to print out the column of a matrix but i keep getting an error.
Error: This expression has type 'a list but an expression was expected of type int
let rec get_column2 mat x = match mat with
| [] -> raise (Failure "empty list")
| h::t -> if x = 1 then h else get_column2 t (x-1);;
let rec get_column mat x= match mat with
| [] -> raise (Failure "empty list")
| []::tv -> get_column tv x
| hv::tv -> get_column2 hv x::get_column tv x;;
Matrix example [[2;5;6];[3;5;3][3;6;8]]
The first part works fine on type int list so I added the second part to go through the int list list and cut them into int list's and then tryed to get the columns of each separately.
I also tryed it this way:
let rec get_column mat x =
let rec column matr y =
if matr = [] then raise (Failure "empty list") else
if y = 1 then List.hd matr else
column (List.tl matr) y-1;
in column (List.hd mat) x :: get_column (List.tl mat) x;;
The second example translates fine but then doesn't work. I get an Exception "tl". (I'm not sure the function nesting is done right since I'm just learning Ocaml).
get_column2 - your first function, works as it should. That is it will fetch the value of each row in the matrix. It's a good helper function for you to extract the value from a list.
Your second function get_column gets all the types right, and you're accumulating everything, except that instead of stopping when you have an empty list [] you end up throwing an exception. That is your matrix example will go through just nicely, until it has no more lists to go through, then it will always throw the exception. (because the recursion keeps going till it's an empty list, and Ocaml will do as you told it too, fail when it gets an empty list.
The only thing you were missing was the exception, instead of throwing an exception, just return an empty list. That way your recursion will go all the way and accumulate till it's an empty list, and at the final step where the matrix is empty, it will append the empty list to the result, and you're golden.
So your code should be:
let rec get_column2 mat x = match mat with
| [] -> raise (Failure "empty list")
| h::t -> if x = 1 then h else get_column2 t (x-1)
let rec get_column mat x= match mat with
| [] -> [] (*doesn't throw an exception here*)
| []::tv -> get_column tv x
| hv::tv -> (get_column2 hv x)::get_column tv x
Instead of throwing the exception when it's an empty list, maybe you could check if the value of x is more than the length of the inner list.
Also, here's my implementation of doing it. It's still fairly basic as it doesn't use List.iter which everyone loves, but it doesn't rely on any additional packages. It makes use of nested functions so you don't expose them everywhere and pollute the namespace.
(*mat is a list of int list*)
let get_col mat x =
let rec helper rows x = (*helper function that gets the value at x*)
match rows with
| [] -> raise (Failure "empty list")
| h::t -> if x = 1 then h else helper t (x-1)
in
let rec wrapper mat= (*function that walks through all the rows*)
match mat with
| [] -> []
| rows::tl -> (helper rows x)::(wrapper tl) (*keep accumulating value*)
in wrapper mat
How you can visualize the [] -> [] part is that when the recursion is at it's final stage (mat is reduced to an empty list), the wrapper function returns the empty list, which will be appended to the recursion stack (since we are accumulating the values in a list as per (helper rows x)::(wrapper tl)), and the recursion will complete.
You don't hit this error with your get_column2 as you tell ocaml to stop recursing and return a value when x=1.
Edit, Additional:
As Jeffrey mentioned, a much more elegant way of handling the error is adding the case for [row], where row is the last row in the matrix. You just return (helper row x) there. And you could have the empty matrix as a failure.
Example using your code:
let rec get_column mat x= match mat with
| [] -> raise (Failure "empty list") (*fail here, as we don't want to compute a matrix with no rows.*)
| [tv] -> get_column tv x (*just return the value*)
| hv::tv -> (get_column2 hv x)::get_column tv x
When I try your first example, I don't get a type error. When I run it, I get the "empty list" failure. So your description of your problem seems wrong.
If you want to treat an empty matrix as an error, you must be very careful to handle a 1 x n matrix as your base case. I don't see that in your code.

Converting a binary tree to a list using fold function in Ocaml

Given:
type 'a tree = Empty | Node of 'a * 'a tree * 'a tree
Use:
let rec tree_fold f e t = match t with
| Empty -> e
| Node (x, l, r) -> f x (tree_fold f e l) (tree_fold f e r);;
to convert a binary tree to a list.
Example.
let someTree = Node (1,Node(2,Node(3,Empty,Empty),Empty),Empty)
tree2list someTree gives [1;2;3].
My attempt:
let tree2list tr = match tr with
| Empty -> Empty
| Node (x,l,r) -> (tree_fold (fun acc tree-> tree::acc) [] tr)
It gives the error:
This expression has type 'a list but an expression was expected of type 'b -> 'b .
I've been at this for hours and keep getting similar errors. Any help would be very appreciated, even just a small hint would be great.
Thanks.
function that you should pass to a tree_fold accepts three arguments, and you're passing a function that can take only two arguments. That's what compiler tries to say. Of course, ther're some other problems, but I hope tha you'll cope with them!

Using continuation / CPS to implement tail-recursive MergeSort in OCaml

I am trying to implement a tail-recursive MergeSort in OCaml.
Since Mergesort naturally is not tail-recursive, so I am using CPS to implement it.
Also my implementation is inspired by Tail-recursive merge sort in OCaml
Below is my code
let merge compare_fun l1 l2 =
let rec mg l1 l2 acc =
match l1, l2 with
| ([], []) -> List.rev acc
| ([], hd2::tl2) -> mg [] tl2 (hd2::acc)
| (hd1::tl1, []) -> mg tl1 [] (hd1::acc)
| (hd1::tl1, hd2::tl2) ->
let c = compare_fun hd1 hd2
in
if c = 1 then mg l1 tl2 (hd2::acc)
else if c = 0 then mg tl1 tl2 (hd2::hd1::acc)
else mg tl1 l2 (hd1::acc)
in
mg l1 l2 [];;
let split_list p l =
let rec split_list p (acc1, acc2) = function
| [] -> (List.rev acc1, List.rev acc2)
| hd::tl ->
if p > 0 then split_list (p-1) (hd::acc1, acc2) tl
else split_list (p-2) (acc1, hd::acc2) tl
in
split_list p ([], []) l;;
let mergeSort_cps compare_fun l =
let rec sort_cps l cf = (*cf = continuation func*)
match l with
| [] -> cf []
| hd::[] -> cf [hd]
| _ ->
let (left, right) = split_list ((List.length l)/2) l
in
sort_cps left (fun leftR -> sort_cps right (fun rightR -> cf (merge compare_fun leftR rightR)))
in
sort_cps l (fun x -> x);;
When I compile it, and run it with a 1,000,000 integers, it gives the error of stackoverflow. Why?
Edit
Here is the code I used for testing:
let compare_int x y =
if x > y then 1
else if x = y then 0
else -1;;
let create_list n =
Random.self_init ();
let rec create n' acc =
if n' = 0 then acc
else
create (n'-1) ((Random.int (n/2))::acc)
in
create n [];;
let l = create_list 1000000;;
let sl = mergeSort_cps compare_int l;;
in http://try.ocamlpro.com/, it gave this error: Exception: RangeError: Maximum call stack size exceeded.
in local ocaml top level, it didn't have any problem
Adding another answer to make a separate point: it seems that much of the confusion among answerers is caused by the fact that you don't use the standard OCaml compiler, but the TryOCaml website which runs a distinct OCaml backend, on top of javascript, and has therefore slightly different optimization and runtime characteristics.
I can reliably reproduce the fact that, on the TryOCaml website, the CPS-style function mergeSort_cps you show fails on lists of length 1_000_000 with the following error:
Exception: InternalError: too much recursion.
My analysis is that this is not due to a lack of tail-rec-ness, but by a lack of support, on the Javascript backend, of the non-obvious way in which the CPS-translated call is tailrec: recursion goes through a lambda-abstraction boundary (but still in tail position).
Turning the code in the direct, non-tail-rec version makes the problem go away:
let rec merge_sort compare = function
| [] -> []
| [hd] -> [hd]
| l ->
let (left, right) = split_list (List.length l / 2) l in
merge compare (merge_sort compare left) (merge_sort compare right);;
As I said in my other answer, this code has a logarithmic stack depth, so no StackOverflow will arise from its use (tail-rec is not everything). It is simpler code that the Javascript backend handles better.
Note that you can make it noticeably faster by using a better implementation split (still with your definition of merge) that avoids the double traversal of List.length then splitting:
let split li =
let rec split ls rs = function
| [] -> (ls, rs)
| x::xs -> split rs (x::ls) xs in
split [] [] li;;
let rec merge_sort compare = function
| [] -> []
| [hd] -> [hd]
| l ->
let (left, right) = split l in
merge compare (merge_sort compare left) (merge_sort compare right);;
Reading the comments, it seems that your Stack_overflow error is hard to reproduce.
Nevertheless, your code is not entirely in CPS or tail-recursive: in merge_sort, the calls to split_list and merge are made in a non-tail-call position.
The question is: by making your CPS transform and generous use of accumulators, what will be the worst stack depth related to recursion? Saving stack depth on the sort calls is in fact not very interesting: as each split the list in two, the worst stack depth would be O(log n) for n the size the input list.
On the contrary, split and merge would have made a linear O(n) usage of the stack if they weren't written in accumulator-passing style, so they are important to make tail-rec. As your implementation of those routines is tail-rec, there should be no need to worry about stack usage, and neither to convert the sort routine itself in CPS form that makes the code harder to read.
(Note that this logarithmic-decrease argument is specific to mergesort. A quicksort can have linear stack usage in worst case, so it could be important to make it tail-rec.)

F# Cutting a list in half using functional programming

I am trying to input a list into the function and it send me a list with the first half of the elements taken away using f# with the below recursion but I keep running into a base case problem that I just cant figure out. any thoughts? I am using the second shadow list to count how far I need to go until I am half way into the list (by removing two elements at a time)
let rec dropHalf listToDrop shadowList =
match shadowList with
| [] -> listToDrop
| shadowHead2::shadowHead1::shadowTail -> if shadowTail.Length<=1 then listToDrop else
match listToDrop with
|[] -> listToDrop
|listToDropHead::listToDropTail -> dropHalf listToDropTail shadowTail
let rec dropHalf listToDrop shadowList =
match shadowList with
| [] -> listToDrop
| shadowHead2::[] -> listToDrop (* odd number! *)
| shadowHead1::shadowHead2::shadowTail ->
match listToDrop with
| [] -> listToDrop (* should never happen? *)
| listToDropHead::listToDropTail -> dropHalf listToDropTail shadowTail
i'm afraid i don't use F#, but it's similar to ocaml, so hopefully the following is close to what you're looking for (maybe the comment format has changed?!). the idea is that when you exhaust the shadow you're done. your code was almost there, but the test for length on the shadow tail made no sense.
i want to emphasize that this isn't anything like anyone would write "in real life", but it sounds like you're battling with some weird requirements.
Because you use the shadow list with the same length as the original list and remove elements from these lists with different rates, it's better to create an auxiliary function:
let dropHalf xs =
let rec dropHalf' ys zs =
match ys, zs with
| _::_::ys', _::zs' -> dropHalf' ys' zs'
| _, zs' -> zs' (* One half of the shadow list ys *)
dropHalf' xs xs
If you don't care to traverse the list twice, the following solution is simpler:
let rec drop n xs =
match xs, n with
| _ when n < 0 -> failwith "n should be greater or equals to 0"
| [], _ -> []
| _, 0 -> xs
| _::xs', _ -> drop (n-1) xs'
let dropHalf xs =
xs |> drop (List.length xs/2)
and another simple solution needs some extra space but doesn't have to use recursion:
let dropHalf xs =
let xa = Array.ofList xs
xa.[xa.Length/2..] |> List.ofArray
As a general rule of thumb, if you're calling Length on a list, then there is most likely a better way to do what you're doing. Length has to iterate the entire list and is therefore O(n).
let secondHalf list =
let rec half (result : 'a list) = function
| a::b::sx -> half result.Tail sx
// uncomment to remove odd value from second half
// | (a::sx) -> result.Tail
| _ -> result
half list list
Here is a sample does what you described.
open System
open System.Collections.Generic
let items = seq { 1 .. 100 } |> Seq.toList
let getBackOfList ( targetList : int list) =
if (targetList.Length = 0) then
targetList
else
let len = targetList.Length
let halfLen = len / 2
targetList |> Seq.skip halfLen |> Seq.toList
let shortList = items |> getBackOfList
("Len: {0}", shortList.Length) |> Console.WriteLine
let result = Console.ReadLine()
Hope this helps

Resources