I am using OCaml to write a function that takes a list of ints and an int element and returns a list of pairs where the first element of every pair is the int element and the second element of the pair is a member from the list. For example, let say I have the number 1 and the list [10; 20; 30] as inputs. I like the function to return [(1, 10); (1, 20); (1, 30)]. I wrote the following function:
let rec f (lst : int list) (elm : int) : (int*int) list =
match lst with
| [] -> failwith "empty list"
| [x] -> [(x, elm)];;
I am getting the following error:
Characters 59-120:
Warning 8: this pattern-matching is not exhaustive.
Here is an example of a value that is not matched:
_::_::_ val f : int list -> int -> (int * int) list = <fun>
What am I missing?
Here is your code
let rec f (lst : int list) (elm : int) : (int*int) list =
match lst with
| [] -> failwith "empty list"
| [x] -> [(x, elm)]
In your match, you listed two cases: [] and [x].
Your first case is [], you mean empty, no problem.
Your second case is [x], what did you want to mean? In OCaml, it means a list with only one element.
How about the cases where there are more than one element?
For any if else or match with, you should include all cases.
When you fix this problem, you will soon find you really missed something more there.
Here is the correct code:
let rec f e l =
match l with
| [] -> []
| x::[] -> [(e,x)]
| x::tl -> (e,x)::(f e tl)
Note
above code is not tail-recursive and you normally should consider about it, I will leave that to you.
you don't need ;; if you write your code in file and compile the file
You don't need to declare types in most cases and that is one of the best thing ocaml has.
Your patterns match lists of length 0 ([]) and of length 1 ([x]). The compiler is telling you that there are other lengths that a list might have, so your pattern is probably wrong (which is true).
I might note that it's not an error to get an empty list as an argument. Thinking this way will make it much harder to answer the problem. If you get an empty list, the correct answer is an empty list of pairs.
let rec f e = function
| [] -> []
| x::tl -> (e,x)::f e tl
Or
let f e = List.map (fun x -> (e,x))
Test
# f 1 [];;
- : (int * 'a) list = []
# f 1 [10;20;30];;
- : (int * int) list = [(1, 10); (1, 20); (1, 30)]
Related
Hello I'm trying to write a program in OCaml and was wondering if there is a way to get from list of pairs : [(1,2);(2,3);(3;5)] to a list where pairs are multiplied [2;6;15] this is what i have tried but it's giving me Exception: Failure "hd"
let rec mul l=
let x=(List.hd l) and y=(List.tl l) in
((fst x)*(snd x))::(mul y);;
mul [(3, 5); (3, 4); (3, 3);];;
What you want essentially is List.map (uncurry ( * )).
# let uncurry f (a, b) = f a b;;
val uncurry : ('a -> 'b -> 'c) -> 'a * 'b -> 'c = <fun>
# List.map (uncurry ( * )) [(3, 5); (3, 4); (3, 3);];;
- : int list = [15; 12; 9]
(uncurry is a basic FP function, but unfortunately it isn't defined in OCaml's fairly sparse standard library. But as you can see the definition is straightforward.)
To be honest, I think there must be simpler methods. Specifically, you have a list of n elements which are pairs (so a list of type (int * int) list) and you want to get a list of the same size, but which is the result of multiplying the two members of the pair. So, going from an (int * int) list to an int list.
As the objective is to preserve the size of the list, you can rephrase the statement by saying "I would like to apply a function on each element of my list". It is possible to do this manually, using, for example, pattern matching (which makes it possible to be explicit about the treatment of the empty list):
let rec mult my_list =
match my_list with
| [] -> (* case if my list is empty *)
[] (* The process is done! *)
| (a, b) :: tail -> (* if I have, at least, one element)
(a * b) :: (mult tail)
But generally, applying a function to each element of a list and preserving its size is called "mapping" (roughly), and fortunately there is a function in the standard OCaml library which allows this, and it is called, logically: List.map, here is its type: val map : ('a -> 'b) -> 'a list -> 'b list which could be translated as: give me a function which goes from 'a to 'b, a list of 'a and I can produce a list of 'b for you.
Here, we would like to be able to apply a function that goes from (int * int) -> int, for example: let prod (x, y) = x * y. So let's try to reimplement mult in terms of map:
let mult my_list =
let prod (x, y) = x * y in
List.map prod my_list
And voila, the pattern captured in the first purpose is exactly the idea behind List.map, for each element of a list, I apply a function and I keep the result of the function application.
Here is a working solution with the least amount of modification to your original code:
let rec mul l =
match l with
| [] -> [] (* <-- Deal with the base case *)
| _ -> (* Same as before --> *)
let x = (List.hd l) and y = (List.tl l) in
((fst x)*(snd x))::(mul y);;
Note that we just need to consider that happens when the list is empty, and we do that by matching on the list. The recursive case stays the same.
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
I'm supposed to remove consecutive duplicates from an int list without using recursion and using only List.fold, map, filter, fold_left, fold_right.
I almost got it, but the problem with my code is that it checks if each element equals the 2nd element, and not the next element.
For example if let z = int list [3;1;4;5;5;1;1] my code will return [3;4;5] and not [3;1;4;5;1]. I'm not sure how to change it so filter uses a dynamically changing list parameter and not simply the original one (so it doesn't compare each element to the second element (1 in this case) each time):
let dupe (ls: int list) : int list =
List.filter (fun x -> if List.length ls = 0 then true else if x = List.hd (List.tl xs) then false else true) ls
The type of List.filter is this:
# List.filter;;
- : ('a -> bool) -> 'a list -> 'a list = <fun>
Notably, the filter function can see only one element of the list at a time. You need to see two consecutive elements to decide what to do, so I'd say List.filter won't do the job.
You're going to have to use map or one of the folds, I'd say. You can figure out which one(s) will work, with similar reasoning.
(I assume this is the sort of reasoning the assignment is supposed to illustrate. So I'm going to leave it there.)
Without rec
let remove = function
[] -> []
| x::tl ->
let (_,lxRes)=
List.fold_left (
fun (xPrec,lxRes) xCour ->
if xPrec=xCour then
(xCour,lxRes)
else
(xCour,lxRes#[xCour])
) (x+1,[]) (x::tl)
in
lxRes
Test:
# remove [3;1;4;5;5;1;1];;
- : int list = [3; 1; 4; 5; 1]
# remove [1;1];;
- : int list = [1]
# remove [1;1;1;1;2;2;3;4;5;5];;
- : int list = [1; 2; 3; 4; 5]
With rec (just for information)
let rec remove =
function
| [] -> []
| x::[] -> x::[]
| x::y::tl ->
if x=y then remove (y::tl)
else x::remove (y::tl)
Using just List.fold_left can be a little bit more concise than the previous answer. Of course, this will build up the list in reverse order, so we need to reverse the result.
let remove lst =
List.(
lst
|> fold_left
(fun acc x ->
match acc with
| [] -> [x]
| hd::_ when x = hd -> acc
| _ -> x::acc)
[]
|> rev
)
Of course, if you're not allowed to use List.rev we can reimplement it easily using List.fold_left, List.cons and Fun.flip.
let rev lst =
List.fold_left (Fun.flip List.cons) [] lst
Hello i resolved problem with ealier task.
Now if i have for example list = [ 2; 3; 2 ; 6 ] want to translate it like this [2;5;7;13].
I declared x as my first element and xs as my rest and used List.scan . Idea below
(fun x n -> x + n) 0
but this make something like this
val it : int list = [0; 2; 5; 7; 13]
How to rewrite it to make list looking like this [2;5;7;13] with using any starting parameter. When i delete 0 i get error message.
Another question how it's going to look like List.Fold i tried to write something similar but it can get only sum of this list ;( .
Here's how I would do this with a fold (with type annotations):
let orig = [2; 3; 2; 6]
let workingSum (origList:int list) : int list =
let foldFunc (listSoFar: int list) (item:int) : int list =
let nextValue =
match listSoFar with
| [] -> item
| head::_ -> head + item
nextValue::listSoFar
origList |> List.fold foldFunc [] |> List.rev
For help learning fold, here's how I would do this with a recursive function:
let workingSum' (origList: int list): int list =
let rec loop (listSoFar: int list) (origListRemaining:int list): int list =
match origListRemaining with
| [] -> listSoFar
| remainHead::remainTail ->
let nextValue =
match listSoFar with
| [] -> remainHead
| head::_ -> head + remainHead
loop (nextValue::listSoFar) remainTail
origList |> loop [] |> List.rev
Note that the signature of the inner loop function is really similar to the foldFunc of the previous example, with one major difference: instead of being passed in the next element, it's being passed in the remainder of the original list that hasn't been processed yet. I'm using a match expression to account for the two different possibilities of that remainder of the original list: either the list is empty (meaning we're done), or it's not (and we need to return a recursive call to the next step).
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 []