On defining list length in terms of fold - ocaml

This is just an exercise (I realize that the functions mentioned below are already implemented in List).
Suppose that I have an interface that includes the following lines
val length : 'a list -> int
val fold : init:'acc -> f:('acc -> 'a -> 'acc) -> 'a list -> 'acc
...and that I implement fold like this:
let rec fold ~init ~f l =
match l with
| [] -> init
| h :: t -> fold ~init:(f init h) ~f:f t
I expected to now be able to implement length like this
let length = fold ~init:0 ~f:(fun c _ -> (c + 1))
...but the compiler complains with
Values do not match:
val length : '_a list -> int
is not included in
val length : 'a list -> int
Of course, I know that I can implement length like this
let length l = fold ~init:0 ~f:(fun c _ -> (c + 1)) l
...but I don't understand why I can't remove the trailing l from both sides of the =.
Where am I going wrong?

This is the value restriction. Your definition of length is not a value in a very technical sense. There are some good discussions of the issue already here on Stack Overflow. I'll look for a good one.
Here is a pretty good one:
Why does a partial application have value restriction?

Related

Remove all empty lists from a list of lists Ocaml

please help.
I am trying to write two non-recursive functions in OCaml (a list of lists contains elements that are lists themselves)
clear l which takes a list of lists as an argument and returns the list of lists without empty lists if there are any.
Example: clear [[2];[];[];[3;4;6];[6;5];[]]
will returns
[[2];[3;4;6];[6;5]]
sort_length l that sorts the elements of this list l according to their length. E.g. sort_length [[2];[];[3];[6;5]] returns [[];[2];[3];[6;5]]
I am only allowed to use these predefined functions: List.filter, List.sort, List.hd, List.tl, List.length and no others.
Thanks
For the second function, I have tried this so far, but I used map which is not allowed
let rec insert cmp e = function
| [] -> [e]
| h :: t as l -> if cmp e h <= 0 then e :: l else h :: insert cmp e t
let rec sort cmp = function
| [] -> []
| h :: t -> insert cmp h (sort cmp t)
let sort_length l =
let l = List.map (fun list -> List.length list, list) l in
let l = sort (fun a b -> compare (fst a) (fst b)) l in
List.map snd l;;
Thanks
As mentioned here: https://ocaml.org/api/List.html#VALfilter, List.filter returns all the elements of the list that satisfy the given predicate. So you must write a predicate that describes a list that is not empty. Another way of saying that a list is not empty is to say that "its size is greater than zero". So it would be possible to formulate clear in this way:
let clear list =
let is_not_empty l = (List.length l) > 0 in
List.filter is_not_empty list
Small edit
As mentioned by Chris Dutton, using List.length may be inefficient. Another approach would be to express is_not_empty in this way:
let is_not_empty = function
| [] -> false
| _ -> true
This approach is "better" because it does not require going through the whole list to see if it is empty or not.
For the second point, the List.sort function takes a comparison function between two elements ('a -> 'a -> int), here the comparison must act on the size of the lists.
In other words, the size of the two lists observed must be compared. One way to do this would be to use Int.compare (https://ocaml.org/api/Int.html#VALcompare) on the size of the two observed lists. For example:
let sort_length list =
let compare_length a b =
let la = List.length a in
let lb = List.length b in
Int.compare la lb
in
List.sort compare_length list
There are more concise ways of writing these two functions but these implementations should be fairly clear.

Filtering integers from list of list in OCaml

I am trying to write a function that filters positive integers from a list of list of integers, returning a list of only negative integers.
For example, if I have a list of list such as [[-1; 1]; [1]; [-1;-1]] it would return [[-1]; []; [-1;-1]].
I tried to use filter and transform functions, which was in my textbook.
let rec transform (f:'a -> 'b) (l:'a list) : 'b list =
begin match l with
| [] -> []
| x::tl -> (f x)::(transform f tl)
end
and for filter, I had previously written:
let rec filter (pred: 'a -> bool) (l: 'a list) : 'a list =
begin match l with
| [] -> []
| x :: tl -> if pred x then x :: (filter pred tl) else filter pred tl
end
So, using these, I wrote
let filter_negatives (l: int list list) : int list list =
transform (fun l -> (filter(fun i -> i<0)) + l) [] l
but I'm still having trouble fully understanding anonymous functions, and I'm getting error messages which I don't know what to make of.
This function has type ('a -> 'b) -> 'a list -> 'b list
It is applied to too many arguments; maybe you forgot a `;'.
(For what it's worth this transform function is more commonly called map.)
The error message is telling you a simple, true fact. The transform function takes two arguments: a function and a list. You're giving it 3 arguments. So something must be wrong.
The transformation you want to happen to each element of the list is a filtering. So, if you remove the + (which really doesn't make any sense) from your transforming function you have something very close to what you want.
Possibly you just need to remove the [] from the arguments of transform. It's not clear (to me) why it's there.

Understanding the structure of Ocaml

As I am going through the website:
http://www.cs.princeton.edu/courses/archive/fall14/cos326/sec/03/precept03_sol.ml
I have got a question according to the Ocaml structure. To be more specific, I have questions according to the code:
let rec reduce (f:'a -> 'b -> 'b) (u:'b) (xs:'a list) : 'b =
match xs with
| [] -> u
| hd::tl -> f hd (reduce f u tl);;
What does the f hd do at the very last line? (I understand that reduce f u tl is calling the function itself again.)
My second question is how to use a function to implement another function in Ocaml. For the code:
let times_x (x: int) (lst: int list) : int list =
map (fun y -> y*x) lst
What does fun y -> y*x do? what does lst do at the end of the code?
Thank you for the help!
The code that has been provided is a reduce function that takes three parameters - a function that maps inputs of type 'a and 'b to an output of type 'b, a value of type 'b, and as list of elements of type 'a.
For example, the length example from the lecture:
let length (lst: int list) : int =
reduce (fun _ len -> len + 1) 0 lst
The first parameter to reduce is a function that, when given two parameters, discards the first one and returns the second parameter incremented by one. The second is a value (0) to be used as an accumulator. The third is a list to find the length of.
The behavior of this recursive reduce function is to return the second parameter (an accumulator as used in the length example) once the provided list is empty, and otherwise run the provided function using the head of the list and the recursed value.
Once again going to the length example, say we give it a list with a single element [1].
Our call to length becomes reduce (fun _ len -> len + 1) 0 [1]
Recall reduce:
let rec reduce (f:'a -> 'b -> 'b) (u:'b) (xs:'a list) : 'b =
match xs with
| [] -> u
| hd::tl -> f hd (reduce f u tl);;
First, we match [1] against [], which fails. Since it is a non-empty list, we run f hd (reduce f u tl)
Recall that f is the parameter that length provided: fun _ len -> len + 1
Therefore, we effectively run the following:
(fun _ len -> len + 1) 1 (reduce (fun _ len -> len + 1) 0 [])
In this case, the length function discards the first parameter since the values in the list are not necessary to know the length of the list.
The recursive portion will match against [] and return the value of u at the time, which is 0.
Therefore, one level up, (fun _ len -> len + 1) 1 (reduce (fun _ len -> len + 1) 0 []) becomes (fun _ len -> len + 1) 1 0 and returns 0 + 1, simplifying to our expected value 1, which represents the length of the list.
Now, to your second question, in regards to times_x. This performs a mapping. For example, we can map [1;2;3;4;5] to [3;6;9;12;15] with a mapping fun x -> x * 3.
Here times_x is defined as follows:
let times_x (x: int) (lst: int list) : int list =
map (fun y -> y*x) lst
times_x takes an integer and a list. Using the above example, we could call it with times_x 3 [1;2;3;4;5] to get [3;6;9;12;15].
Beyond this I recommend looking into how map and reduce functions work in general.
I hope this answer was adequate at addressing your question.

Applying Fold function in F#

let list_min_fold = List.fold (fun acc -> List.min acc ) 0 lst
printfn"Using regular List.fold function:\n The minimum is: %A\n"
(list_min_fold)
When I execute my code this error displays:
error FS0001: The type '('a -> 'b)' does not support the 'comparison' constraint. For example, it does not support the 'System.IComparable' interface
Why? Please help :(
Are you trying to find the smallest number in a list? If so, you need to use the min function (which takes just two arguments) rather than List.min (which takes a list of arguments):
To keep the code the most similar to your example, you can write (note also that starting with 0 is not going to work, so I used System.Int32.MaxValue instead):
let lst = [4;3;1;2;5;]
let list_min_fold = List.fold (fun acc -> min acc) System.Int32.MaxValue lst
It is also worth noting that the function you pass to fold takes two arguments - the state acc and the current value:
let list_min_fold = List.fold (fun acc v -> min acc v) System.Int32.MaxValue lst
But thanks to partial function application you can omit one of them (as you did), or both of them:
let list_min_fold = List.fold min System.Int32.MaxValue lst
as always Tomas answer is spot on so I have but a small remark:
as you probably saw it makes no sense to try to find the minimum of an empty list (so the function probably should be of type 'a option and when you have an non-empty list it's very easy to use List.reduce (which is basically just a fold for binary operations and min is a great candidate for such an operation):
let list_min xs =
match xs with
| [] -> None
| _ -> List.reduce min xs
|> Some
this way you get:
> list_min [2;1;5;3];;
val it : int option = Some 1
> list_min [2;1;5;3;0];;
val it : int option = Some 0
> list_min ([] : int list);;
val it : int option = None
ok it's a fair point that the question was about fold - so if it has to be exactly List.fold you can of course do (as TheInnerLight remarked):
let list_min xs =
match xs with
| [] -> None
| (x::xs) -> List.fold min x xs
|> Some

ocaml recursive pattern matching

I'm trying to write a simple recursive function that look over list and return a pair of integer. This is easy to write in c/c++/java but i'm new to ocaml so somehow hard to find out the solution due to type conflict
it should goes like ..
let rec test p l = ... ;;
val separate : (’a -> bool) -> ’a list -> int * int = <fun>
test (fun x -> x mod 2 = 0) [-3; 5; 2; -6];;
- : int * int = (2, 2)
so the problem is how can i recursively return value on tuple ..
One problem here is that you are returning two different types: an int for an empty list, or a tuple otherwise. It needs to be one or the other.
Another problem is that you are trying to add 1 to test, but test is a function, not a value. You need to call test on something else for it to return a value, but even then it is supposed to return a tuple, which you can't add to an integer.
I can't figure out what you want the code to do, but if you update your question with that info I can help more.
One guess that I have is that you want to count the positive numbers in the list, in which case you could write it like this:
let rec test l =
match l with [] -> 0
| x::xs -> if x > 0 then 1 + (test xs)
else test xs;;
Update: since you've edited to clarify the problem, modify the above code as follows:
let test l =
let rec test_helper l pos nonpos =
match l with [] -> (pos, nonpos)
| x::xs -> if x > 0 then test_helper xs 1+pos, nonpos
else test_helper xs pos 1+nonpos
in test_helper l 0 0;;
Using the accumulators help a lot in this case. It also makes the function tail-recursive which is always good practice.
Been away from OCaml for a bit, but I think this will do the trick in regards to REALFREE's description in the comment
let rec test l =
match l with
[] -> (0,0)
| x::xs ->
if x > 0 then match (test xs) with (x,y) -> (x+1, y)
else match (test xs) with (x,y) -> (x, y+1);;
You can used the nested match statements to pull out pieces of the tuple to modify
EDIT:
I didn't know about the syntax Pascal Cuoq mentioned in his comment below, here's the code like that, it's neater and a little shorter:
let rec test l =
match l with
[] -> (0,0)
| x::xs ->
if x > 0 then let (x,y) = test xs in (x+1, y)
else let (x,y) = test xs in (x, y+1);;
But the accepted answer is still much better, especially with the tail recursion ;).