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.
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.
I am very new to F# and functional programming in general, and would like to recursively create a function that takes a list, and doubles all elements.
This is what I used to search for a spacific element, but im not sure how exactly I can change it to do what I need.
let rec returnN n theList =
match n, theList with
| 0, (head::_) -> head
| _, (_::theList') -> returnN (n - 1) theList'
| _, [] -> invalidArg "n" "n is larger then list length"
let list1 = [5; 10; 15; 20; 50; 25; 30]
printfn "%d" (returnN 3 list1 )
Is there a way for me to augment this to do what I need to?
I would like to take you through the thinking process.
Step 1. I need a recursive function that takes a list and doubles all the elements:
So, let's implement this in a naive way:
let rec doubleAll list =
match list with
| [] -> []
| hd :: tl -> hd * 2 :: doubleAll tl
Hopefully this logic is quite simple:
If we have an empty list, we return another empty list.
If we have a list with at least one element, we double the element and then prepend that to the result of calling the doubleAll function on the tail of the list.
Step 2. Actually, there are two things going on here:
I want a function that lets me apply another function to each element of a list.
In this case, I want that function to be "multiply by 2".
So, now we have two functions, let's do a simple implementation like this:
let rec map f list =
match list with
| [] -> []
| hd :: tl -> f hd :: map f tl
let doubleAll list = map (fun x -> x * 2) list
Step 3. Actually, the idea of map is such a common one that it's already built into the F# standard library, see List.map
So, all we need to do is this:
let doubleAll list = List.map (fun x -> x * 2) list
With a list of integers such as:
[1;2;3;4;5;6;7;8;9]
How can I create a list of list of ints from the above, with all new lists the same specified length?
For example, I need to go from:
[1;2;3;4;5;6;7;8;9] to [[1;2;3];[4;5;6];[7;8;9]]
with the number to split being 3?
Thanks for your time.
So what you actually want is a function of type
val split : int list -> int -> int list list
that takes a list of integers and a sub-list-size. How about one that is even more general?
val split : 'a list -> int -> 'a list list
Here comes the implementation:
let split xs size =
let (_, r, rs) =
(* fold over the list, keeping track of how many elements are still
missing in the current list (csize), the current list (ys) and
the result list (zss) *)
List.fold_left (fun (csize, ys, zss) elt ->
(* if target size is 0, add the current list to the target list and
start a new empty current list of target-size size *)
if csize = 0 then (size - 1, [elt], zss # [ys])
(* otherwise decrement the target size and append the current element
elt to the current list ys *)
else (csize - 1, ys # [elt], zss))
(* start the accumulator with target-size=size, an empty current list and
an empty target-list *)
(size, [], []) xs
in
(* add the "left-overs" to the back of the target-list *)
rs # [r]
Please let me know if you get extra points for this! ;)
The code you give is a way to remove a given number of elements from the front of a list. One way to proceed might be to leave this function as it is (maybe clean it up a little) and use an outer function to process the whole list. For this to work easily, your function might also want to return the remainder of the list (so the outer function can easily tell what still needs to be segmented).
It seems, though, that you want to solve the problem with a single function. If so, the main thing I see that's missing is an accumulator for the pieces you've already snipped off. And you also can't quit when you reach your count, you have to remember the piece you just snipped off, and then process the rest of the list the same way.
If I were solving this myself, I'd try to generalize the problem so that the recursive call could help out in all cases. Something that might work is to allow the first piece to be shorter than the rest. That way you can write it as a single function, with no accumulators
(just recursive calls).
I would probably do it this way:
let split lst n =
let rec parti n acc xs =
match xs with
| [] -> (List.rev acc, [])
| _::_ when n = 0 -> (List.rev acc, xs)
| x::xs -> parti (pred n) (x::acc) xs
in let rec concat acc = function
| [] -> List.rev acc
| xs -> let (part, rest) = parti n [] xs in concat (part::acc) rest
in concat [] lst
Note that we are being lenient if n doesn't divide List.length lst evenly.
Example:
split [1;2;3;4;5] 2 gives [[1;2];[3;4];[5]]
Final note: the code is very verbose because the OCaml standard lib is very bare bones :/ With a different lib I'm sure this could be made much more concise.
let rec split n xs =
let rec take k xs ys = match k, xs with
| 0, _ -> List.rev ys :: split n xs
| _, [] -> if ys = [] then [] else [ys]
| _, x::xs' -> take (k - 1) xs' (x::ys)
in take n xs []
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.