This question uses the following "lazy list" (aka "stream") type:
type 'a lazylist = Cons of 'a * (unit -> 'a lazylist)
My question is: how to define a tail-recursive function lcycle that takes a non-empty (and non-lazy) list l as argument, and returns the lazylist corresponding to repeatedly cycling over the elements l. For example:
# ltake (lcycle [1; 2; 3]) 10;;
- : int list = [1; 2; 3; 1; 2; 3; 1; 2; 3; 1]
(ltake is a lazy analogue of List::take; I give one implementation at the end of this post.)
I have implemented several non-tail-recursive versions of lcycles, such as:
let lcycle l =
let rec inner l' =
match l' with
| [] -> raise (Invalid_argument "lcycle: empty list")
| [h] -> Cons (h, fun () -> inner l)
| h::t -> Cons (h, fun () -> inner t)
in inner l
...but I have not managed to write a tail-recursive one.
Basically, I'm running into the problem that lazy evaluation is implemented by constructs of the form
Cons (a, fun () -> <lazylist>)
This means that all my recursive calls happen within such a construct, which is incompatible with tail recursion.
Assuming the lazylist type as defined above, is it possible to define a tail-recursive lcycle? Or is this inherently impossible with OCaml?
EDIT: My motivation here is not to "fix" my implementation of lcycle by making it tail-recursive, but rather to find out whether it is even possible to implement a tail recursive version of lcycle, given the definition of lazylist above. Therefore, pointing out that my lcycle is fine misses what I'm trying to get at. I'm sorry I did not make this point sufficiently clear in my original post.
This implementation of ltake, as well as the definition of the lazylist type above, comes from here:
let rec ltake (Cons (h, tf)) n =
match n with
0 -> []
| _ -> h :: ltake (tf ()) (n - 1)
I don't see much of a problem with this definition. The call to inner is within a function which won't be invoked until lcycle has returned. Thus there is no stack safety issue.
Here's an alternative which moves the empty list test out of the lazy loop:
let lcycle = function
| [] -> invalid_arg "lcycle: empty"
| x::xs ->
let rec first = Cons (x, fun () -> inner xs)
and inner = function
| [] -> first
| y::ys -> Cons (y, fun () -> inner ys) in
first
The problem is that you're trying to solve a problem that doesn't exist. of_list function will not take any stack space, and this is why lazy lists are so great. Let me try to explain the process. When you apply of_list function to a non empty list, it creates a Cons of the head of the list and a closure, that captures a reference to the tail of the list. Afterwards it momentary returns. Nothing more. So it takes only few words of memory, and none of them uses stack. One word contains x value, another contains a closure, that captures only a pointer to the xs.
So then, you deconstruct this pair, you got the value x that you can use right now, and function next, that is indeed the closure that, when invoked, will be applied to a list and if it is nonempty, will return another Cons. Note, that previous cons will be already destroyed to junk, so new memory won't be used.
If you do not believe, you can construct an of_list function that will never terminate (i.e., will cycle over the list), and print it with a iter function. It will run for ever, without taking any memory.
type 'a lazylist = Cons of 'a * (unit -> 'a lazylist)
let of_list lst =
let rec loop = function
| [] -> loop lst
| x :: xs -> Cons (x, fun () -> loop xs) in
loop lst
let rec iter (Cons (a, next)) f =
f a;
iter (next ()) f
Related
Important: I am only allowed to use List.head, List.tail and List.length
No List.map List.rev ...........etc
Only List.hd, List.tl and List.length
How to duplicate the elements of a list in a list of lists only if the length of the list is odd
Here is the code I tried:
let rec listes_paires x =
if x=[] then []
else [List.hd (List.hd x)]
# (List.tl (List.hd x))
# listes_paires (List.tl x);;
(* editor's note: I don't know where this line is supposed to go*)
if List.length mod 2 = 1 then []
For exemple:
lists_odd [[]; [1];[1;2];[1;2;3];[];[5;4;3;2;1]];;
returns
[[]; [1; 1]; [1; 2]; [1; 2; 3; 1; 2; 3]; []; [5; 4; 3; 2; 1; 5; 4; 3; 2; 1]]
Any help would be very appreciated
thank you all
It looks like that your exercise is about writing recursive functions on lists so that you can learn how to write functions like List.length, List.filter, and so on.
Start with the most simple recursive function, the one that computes the length to the list. Recall, that you can pattern match on the input list structure and make decisions on it, e.g.,
let rec length xs = match xs with
| [] -> 0 (* the empty list has size zero *)
| hd :: tl ->
(* here you can call `length` and it will return you
the length of the list hing how you can use it to
compute the length of the list that is made of `tl`
prepended with `hd` *)
???
The trick is to first write the simple cases and then write the complex cases assuming that your recursive function already works. Don't overthink it and don't try to compute how recursion will work in your head. It will make it hurt :) Just write correctly the base cases (the simple cases) and make sure that you call your function recursively and correctly combine the results while assuming that it works correctly. It is called the induction principle and it works, believe me :)
The above length function was easy as it was producing an integer as output and it was very easy to build it, e.g., you can use + to build a new integer from other integers, something that we have learned very early in our lives so it doesn't surprise us. But what if we want to build something more complex (in fact it is not more complex but just less common to us), e.g., a list data structure? Well, it is the same, we can just use :: instead of + to add things to our result.
So, lets try writing the filter function that will recurse over the input list and build a new list from the elements that satisfy the given predicate,
let rec filter xs keep = match xs with
| [] -> (* the simple case - no elements nothing to filter *)
[]
| x :: xs ->
(* we call filter and it returns the correctly filtered list *)
let filtered = filter xs keep in
(* now we need to decide what to do with `x` *)
if keep x then (* how to build a list from `x` and `filtered`?*)
else filtered (* keep filtering *)
The next trick to learn with recursive functions is how to employ helper functions that add an extra state (also called an accumulator). For example, the rev function, which reverses a list, is much better to define with an extra accumulator. Yes, we can easily define it without it,
let rec rev xs = match xs with
| [] -> []
| x :: xs -> rev xs # [x]
But this is an extremely bad idea as # operator will have to go to the end of the first list and build a completely new list on the road to add only one element. That is our rev implementation will have quadratic performance, i.e., for a list of n elements it will build n list each having n elements in it, only to drop most of them. So a more efficient implementation will employ a helper function that will have an extra parameter, an accumulator,
let rev xs =
(* we will pump elements from xs to ys *)
let rec loop xs ys = match xs with
| [] -> ys (* nothing more to pump *)
| x :: xs ->
let ys = (* push y to ys *) in
(* continue pumping *) in
loop xs []
This trick will also help you in implementing your tasks, as you need to filter by the position of the element. That means that your recursive function needs an extra state that counts the position (increments by one on each recursive step through the list elements). So you will need a helper function with an extra parameter for that counter.
Hello All I am trying to flatten a list in Ocaml. I am a newbie so please pardon me if my mistake is dumb
So for example, if input is [[1];[2;3];[4]] I should end up with [1;2;3;4].
The idea I am trying to use is as follows
Iterate through the list from the right (Using fold_right) with accumaltor = []
The pseudo code is as follows
func flatten(list, accumalator)
For each item from right to left in list
If Item is a scalar then n :: accumalator
Else fi Item is a list of form head :: tail then
head :: flatten (tail, accumalator).
I think that theoretically the algorithm is correct, but please let me know if you disagree.
Now to my OCaml code to implement this algorithm
let rec flatten acc x =
match x with
n -> n :: acc
| [x] -> x :: acc
| head :: remainder ->
head :: ( my_flat acc remainder )
and my_flat = List.fold_right flatten
;;
my_flat [] [[1];[2;3];[4]]
The Error I get is the following
Error: This expression has type 'a but an expression was expected of type
'a list
The error occurs on the line that reads head :: ( my_flat acc remainder ) in the last pattern in the match statement
Any help is appreciated.
In OCaml, all the elements of a list must be the same type. Thus the value [1; [2; 3]; 4] is invalid all by itself. It contains two elements that are of type int and one element of type int list. In essence, your statement of the problem to be solved is impossible.
$ ocaml312
Objective Caml version 3.12.0
# [1; [2; 3]; 4];;
Characters 4-10:
[1; [2; 3]; 4];;
^^^^^^
Error: This expression has type 'a list
but an expression was expected of type int
This sounds like a homework problem, so I'll just say that restricting yourself to lists that are valid in OCaml may make it easier to solve.
Edit
OK, the problem can now be solved!
The essence of the reported type error is something like this. You have your accumulated result acc (of type int list in the example). You want to add the list x (also of type int list) to it. You've broken x into head (an int) and remainder (an int list). As you can see, remainder is not a suitable argument for your my_flat function. It wants an int list list, i.e., a list of lists of ints. In fact, your recursive call should almost certainly go to flatten and not to my_flat.
Another problem I see: the arguments of List.fold_right are: a function, a list, and a starting value. In your test call to my_flat, you're supplying the last two in the other order. The empty list [] is your starting value.
I hope this is enough to get you going. Since you're just starting out with OCaml there will probably be another problem or two before it works.
Edit 2
Here are a couple more comments, which might be spoilers if you're still working on your own solution....
A tidier version of your function my_flat is in the OCaml standard library under the name List.flatten. It's interesting to look at the implementation:
let rec flatten = function
[] -> []
| l::r -> l # flatten r
I'd call this a very elegant solution, but unfortunately it's not tail recursive. So it will consume some (linear) amount of stack space, and might even crash for a very long list.
Here's one based on the same idea, using the standard FP accumulator trick to get tail recursive behavior (as noted by Thomas):
let flatten2 ll =
let rec go acc = function
| [] -> List.rev acc
| l :: r -> go (List.rev_append l acc) r
in
go [] ll
As is often the case, the tail recursive version accumulates the result in reverse order, and reverses it at the end.
You can start by writing directly your algorithm, by decomposing the base cases of your input value, ie. the input list is either empty, or the head of the input list is empty, or the head of the input list has a head and a tail:
let rec flatten = function
| [] -> []
| [] :: t -> flatten t
| (x::y) :: t -> x :: (flatten (y::t))
You can then optimize the function, because this code is not tail-recursive and thus will crash when lists become too big. So you can rewrite this by using the usual technique:
let flatten list =
let rec aux accu = function
| [] -> accu
| [] :: t -> aux accu t
| (x::y) :: t -> aux (x::accu) (y::t) in
List.rev (aux [] list)
So my advice is: start by decomposing your problem based on the input types, and then later use accumulators to optimize your code.
I like this one, where the auxiliary function takes the accumulator, the first element of the list of lists, and the rest of the list of lists, it is clearer for me :
let flatten list =
let rec aux acc list1 list2 =
match list1 with
| x :: tail -> aux (x :: acc) tail list2
| [] ->
match list2 with
| [] -> List.rev acc
| x :: tail -> aux acc x tail
in
aux [] [] list
Thanks for all your help
Here is the code I used to solve this problem
let flatten list =
let rec flatten_each acc x =
match x with
[] -> acc
| head :: remainder -> head :: ( flatten_each acc remainder )
in
List.fold_right flatten_each ( List.rev list ) []
;;
Edit: as pointed out by Thomas this solution is not tail recursive. Tail recursive version is below
let flatten list =
let rec flatten_each acc x =
match x with
[] -> acc
| head :: remainder -> (flatten_each (acc # [head]) remainder )
in
List.fold_right flatten_each list []
;;
First off, I apologize if this is a confusing or backwards way to go about what I want to accomplish, but I'm new to "OCaml style".
I want to take the last element of a list, and move it to the front of the list, shifting all the elements up one.
For example: have [1;2;3;4;5] -> [5;1;2;3;4]
I understand that lists in OCaml are basically linked list, so I plan to recursively iterate through the list, find the last element, and then have that element's tail/remaining list point to the head of the list.
What I'm mainly confused about is how to break the link from the second last element to the last element. In the example above, I want to have the 5 point to the 1, but the 4 to no longer point to the 5.
How do I accomplish this, and is there a simpler way to look at this that I'm completely missing?
You can't "Break the link" because Ocaml lists are a persistent data-structure. You can't really modify the lists, so you have to produce a new list with the values in the order you want.
let thelist = [1;2;3;4;5] in
let lnewhead = List.hd (List.rev thelist) in
lnewhead :: (List.rev (List.tl (List.rev b)));;
You could also define this in a function:
let flipper = fun thelist ->
(List.hd (List.rev thelist)) :: (List.rev (List.tl (List.rev thelist)));;
val flipper : 'a list -> 'a list = <fun>
# flipper([1;2;3;4;5]);;
- : int list = [5; 1; 2; 3; 4]
Joshua's code can be slightly improved in terms of time complexity by making sure List.rev thelist is computed only once, as in:
let flipper =
fun thelist ->
let r = List.rev thelist in
List.hd r :: List.rev (List.tl r)
A safe implementation is the following:
let rot1 l =
let rec aux acc = function
[] -> []
| [x] -> x :: List.rev acc
| x :: l -> aux (x :: acc) l
in
aux [] l
It is safe in the sense that passing the empty list returns the empty list instead of raising an exception. Note that I strongly discourage the use of List.hd and List.tl because they may fail, with a generic error message.
Also, the recursive call to aux is a tail call (last thing to do before returning). The OCaml compilers will detect this and avoid growing the stack with each function call (and possibly raise an exception or crash). This is something to be aware of when dealing with long lists and recursive functions.
In order to do this operation efficiently, i.e. in O(1) rather than O(length), you cannot use a regular list. You can use the Queue module from the standard library or implementations of doubly-linked lists provided by third parties.
Here is an example using the Queue module:
let rotate_queue q =
if not (Queue.is_empty q) then
let x = Queue.take q in
Queue.add x q
# let q = Queue.create ();;
val q : '_a Queue.t = <abstr>
# Queue.add 1 q;;
- : unit = ()
# Queue.add 2 q;;
- : unit = ()
# Queue.add 3 q;;
- : unit = ()
# Queue.iter print_int q;;
123- : unit = ()
# rotate_queue q;;
- : unit = ()
# Queue.iter print_int q;;
231- : unit = ()
#
The Dllist module of the Batteries library might be what you are looking for. It is an imperative list structure.
I'm working with a list of lists in OCaml, and I'm trying to write a function that combines all of the lists that share the same head. This is what I have so far, and I make use of the List.hd built-in function, but not surprisingly, I'm getting the failure "hd" error:
let rec combineSameHead list nlist = match list with
| [] -> []#nlist
| h::t -> if List.hd h = List.hd (List.hd t)
then combineSameHead t nlist#uniq(h#(List.hd t))
else combineSameHead t nlist#h;;
So for example, if I have this list:
[[Sentence; Quiet]; [Sentence; Grunt]; [Sentence; Shout]]
I want to combine it into:
[[Sentence; Quiet; Grunt; Shout]]
The function uniq I wrote just removes all duplicates within a list. Please let me know how I would go about completing this. Thanks in advance!
For one thing, I generally avoid functions like List.hd, as pattern maching is usually clearer and less error-prone. In this case, your if can be replaced with guarded patterns (a when clause after the pattern). I think what is happening to cause your error is that your code fails when t is []; guarded patterns help avoid this by making the cases more explicit. So, you can do (x::xs)::(y::ys)::t when x = y as a clause in your match expression to check that the heads of the first two elements of the list are the same. It's not uncommon in OCaml to have several successive patterns which are identical except for guards.
Further things: you don't need []#nlist - it's the same as just writing nlist.
Also, it looks like your nlist#h and similar expressions are trying to concatenate lists before passing them to the recursive call; in OCaml, however, function application binds more tightly than any operator, so it actually appends the result of the recursive call to h.
I don't, off-hand, have a correct version of the function. But I would start by writing it with guarded patterns, and then see how far that gets you in working it out.
Your intended operation has a simple recursive description: recursively process the tail of your list, then perform an "insert" operation with the head which looks for a list that begins with the same head and, if found, inserts all elements but the head, and otherwise appends it at the end. You can then reverse the result to get your intended list of list.
In OCaml, this algorithm would look like this:
let process list =
let rec insert (head,tail) = function
| [] -> head :: tail
| h :: t ->
match h with
| hh :: tt when hh = head -> (hh :: (tail # t)) :: t
| _ -> h :: insert (head,tail) t
in
let rec aux = function
| [] -> []
| [] :: t -> aux t
| (head :: tail) :: t -> insert (head,tail) (aux t)
in
List.rev (aux list)
Consider using a Map or a hash table to keep track of the heads and the elements found for each head. The nlist auxiliary list isn't very helpful if lists with the same heads aren't adjacent, as in this example:
# combineSameHead [["A"; "a0"; "a1"]; ["B"; "b0"]; ["A"; "a2"]]
- : list (list string) = [["A"; "a0"; "a1"; "a2"]; ["B"; "b0"]]
I probably would have done something along the lines of what antonakos suggested. It would totally avoid the O(n) cost of searching in a list. You may also find that using a StringSet.t StringMap.t be easier on further processing. Of course, readability is paramount, and I still find this hold under that criteria.
module OrderedString =
struct
type t = string
let compare = Pervasives.compare
end
module StringMap = Map.Make (OrderedString)
module StringSet = Set.Make (OrderedString)
let merge_same_heads lsts =
let add_single map = function
| hd::tl when StringMap.mem hd map ->
let set = StringMap.find hd map in
let set = List.fold_right StringSet.add tl set in
StringMap.add hd set map
| hd::tl ->
let set = List.fold_right StringSet.add tl StringSet.empty in
StringMap.add hd set map
| [] ->
map
in
let map = List.fold_left add_single StringMap.empty lsts in
StringMap.fold (fun k v acc-> (k::(StringSet.elements v))::acc) map []
You can do a lot just using the standard library:
(* compares the head of a list to a supplied value. Used to partition a lists of lists *)
let partPred x = function h::_ -> h = x
| _ -> false
let rec combineHeads = function [] -> []
| []::t -> combineHeads t (* skip empty lists *)
| (hh::_ as h)::t -> let r, l = List.partition (partPred hh) t in (* split into lists with the same head as the first, and lists with different heads *)
(List.fold_left (fun x y -> x # (List.tl y)) h r)::(combineHeads l) (* combine all the lists with the same head, then recurse on the remaining lists *)
combineHeads [[1;2;3];[1;4;5;];[2;3;4];[1];[1;5;7];[2;5];[3;4;6]];;
- : int list list = [[1; 2; 3; 4; 5; 5; 7]; [2; 3; 4; 5]; [3; 4; 6]]
This won't be fast (partition, fold_left and concat are all O(n)) however.
I'm currently trying to extend a friend's OCaml program. It's a huge collection of functions needed for some data analysis.. Since I'm not really an OCaml crack I'm currently stuck on a (for me) strange List implementation:
type 'a cell = Nil
| Cons of ('a * 'a llist)
and 'a llist = (unit -> 'a cell);;
I've figured out that this implements some sort of "lazy" list, but I have absolutely no idea how it really works. I need to implement an Append and a Map Function based on the above type. Has anybody got an idea how to do that?
Any help would really be appreciated!
let rec append l1 l2 =
match l1 () with
Nil -> l2 |
(Cons (a, l)) -> fun () -> (Cons (a, append l l2));;
let rec map f l =
fun () ->
match l () with
Nil -> Nil |
(Cons (a, r)) -> fun () -> (Cons (f a, map f r));;
The basic idea of this implementation of lazy lists is that each computation is encapsulated in a function (the technical term is a closure) via fun () -> x.
The expression x is then only evaluated when the function is applied to () (the unit value, which contains no information).
It might help to note that function closures are essentially equivalent to lazy values:
lazy n : 'a Lazy.t <=> (fun () -> n) : unit -> 'a
force x : 'a <=> x () : 'a
So the type 'a llist is equivalent to
type 'a llist = 'a cell Lazy.t
i.e., a lazy cell value.
A map implementation might make more sense in terms of the above definition
let rec map f lst =
match force lst with
| Nil -> lazy Nil
| Cons (hd,tl) -> lazy (Cons (f hd, map f tl))
Translating that back into closures:
let rec map f lst =
match lst () with
| Nil -> (fun () -> Nil)
| Cons (hd,tl) -> (fun () -> Cons (f hd, map f tl))
Similarly with append
let rec append a b =
match force a with
| Nil -> b
| Cons (hd,tl) -> lazy (Cons (hd, append tl b))
becomes
let rec append a b =
match a () with
| Nil -> b
| Cons (hd,tl) -> (fun () -> Cons (hd, append tl b))
I generally prefer to use the lazy syntax, since it makes it more clear what's going on.
Note, also, that a lazy suspension and a closure are not exactly equivalent. For example,
let x = lazy (print_endline "foo") in
force x;
force x
prints
foo
whereas
let x = fun () -> print_endline "foo" in
x ();
x ()
prints
foo
foo
The difference is that force computes the value of the expression exactly once.
Yes, the lists can be infinite. The code given in the other answers will append to the end of an infinite list, but there's no program you can write than can observe what is appended following an infinite list.