I am trying to implement something like a pipe function.
Input: a list of functions
Output: a function
Example:
# pipe [(fun y -> y+5);(fun y -> y*3)] 1 = 18
# pipe [(fun z -> z*3);(fun z -> z+5)] 1 = 8
My problem:
A helper function composite takes two arguments, which are a function f and a list of function l. If the list is empty, it returns the function f.
If it is not, f will be an argument of the head of list g.
However, I got a syntax error. I don't figure out what's going on.
Has anyone found an error?
let pipe l =
let composite f l = match l with
[]->f
| g::gs -> (fun h -> (g -> f)) in
List.fold_left composite (fun x -> x) l
(fun h -> (g -> f)) is not syntactically correct, and I'm not sure what it is supposed to mean.
The pattern-matching of your composite function looks like what you would write for a recursive function, but then you're trying to define it non-recursively for use with fold_left. Either way would be good, but you need to make up your mind, because here you've a sad compromise that does not work.
Related
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.
Implementing Haskell's take and drop functions using foldl.
Any suggestions on how to implement take and drop functions using foldl ??
take x ls = foldl ???
drop x ls = foldl ???
i've tried these but it's showing errors:
myFunc :: Int -> [a] -> [a]
myFunc n list = foldl func [] list
where
func x y | (length y) > n = x : y
| otherwise = y
ERROR PRODUCED :
*** Expression : foldl func [] list
*** Term : func
*** Type : a -> [a] -> [a]
*** Does not match : [a] -> [a] -> [a]
*** Because : unification would give infinite type
Can't be done.
Left fold necessarily diverges on infinite lists, but take n does not. This is so because left fold is tail recursive, so it must scan through the whole input list before it can start the processing.
With the right fold, it's
ntake :: Int -> [a] -> [a]
ntake 0 _ = []
ntake n xs = foldr g z xs 0
where
g x r i | i>=n = []
| otherwise = x : r (i+1)
z _ = []
ndrop :: Int -> [a] -> [a]
ndrop 0 xs = xs
ndrop n xs = foldr g z xs 0 xs
where
g x r i xs#(_:t) | i>=n = xs
| otherwise = r (i+1) t
z _ _ = []
ndrop implements a paramorphism nicely and faithfully, up to the order of arguments to the reducer function g, giving it access to both the current element x and the current list node xs (such that xs == (x:t)) as well as the recursive result r. A catamorphism's reducer has access only to x and r.
Folds usually encode catamorphisms, but this shows that right fold can be used to code up a paramorphism just as well. It's universal that way. I think it is beautiful.
As for the type error, to fix it just switch the arguments to your func:
func y x | ..... = .......
The accumulator in the left fold comes as the first argument to the reducer function.
If you really want it done with the left fold, and if you're really sure the lists are finite, two options:
ltake n xs = post $ foldl' g (0,id) xs
where
g (i,f) x | i < n = (i+1, f . (x:))
| otherwise = (i,f)
post (_,f) = f []
rltake n xs = foldl' g id xs r n
where
g acc x = acc . f x
f x r i | i > 0 = x : r (i-1)
| otherwise = []
r _ = []
The first counts from the left straight up, potentially stopping assembling the prefix in the middle of the full list traversal that it does carry to the end nevertheless, being a left fold.
The second also traverses the list in full turning it into a right fold which then gets to work counting down from the left again, being able to actually stop working as soon as the prefix is assembled.
Implementing drop this way is bound to be (?) even clunkier. Could be a nice exercise.
I note that you never specified the fold had to be over the supplied list. So, one approach that meets the letter of your question, though probably not the spirit, is:
sillytake :: Int -> [a] -> [a]
sillytake n xs = foldl go (const []) [1..n] xs
where go f _ (x:xs) = x : f xs
go _ _ [] = []
sillydrop :: Int -> [a] -> [a]
sillydrop n xs = foldl go id [1..n] xs
where go f _ (_:xs) = f xs
go _ _ [] = []
These each use left folds, but over the list of numbers [1..n] -- the numbers themselves are ignored, and the list is just used for its length to build a custom take n or drop n function for the given n. This function is then applied to the original supplied list xs.
These versions work fine on infinite lists:
> sillytake 5 $ sillydrop 5 $ [1..]
[6,7,8,9,10]
Will Ness showed a nice way to implement take with foldr. The least repulsive way to implement drop with foldr is this:
drop n0 xs0 = foldr go stop xs0 n0
where
stop _ = []
go x r n
| n <= 0 = x : r 0
| otherwise = r (n - 1)
Take the efficiency loss and rebuild the whole list if you have no choice! Better to drive a nail in with a screwdriver than drive a screw in with a hammer.
Both ways are horrible. But this one helps you understand how folds can be used to structure functions and what their limits are.
Folds just aren't the right tools for implementing drop; a paramorphism is the right tool.
You are not too far. Here are a pair of fixes.
First, note that func is passed the accumulator first (i.e. a list of a, in your case) and then the list element (an a). So, you need to swap the order of the arguments of func.
Then, if we want to mimic take, we need to add x when the length y is less than n, not greater!
So we get
myFunc :: Int -> [a] -> [a]
myFunc n list = foldl func [] list
where
func y x | (length y) < n = x : y
| otherwise = y
Test:
> myFunc 5 [1..10]
[5,4,3,2,1]
As you can see, this is reversing the string. This is because we add x at the front (x:y) instead of at the back (y++[x]). Or, alternatively, one could use reverse (foldl ....) to fix the order at the end.
Also, since foldl always scans the whole input list, myFunc 3 [1..1000000000] will take a lot of time, and myFunc 3 [1..] will fail to terminate. Using foldr would be much better.
drop is more tricky to do. I don't think you can easily do that without some post-processing like myFunc n xs = fst (foldl ...) or making foldl return a function which you immediately call (which is also a kind of post-processing).
In Reason (and OCaml), there is a non-traditional way of passing arguments using the |> operator. What is the convention for when it should be used? I am currently using it all over the place just because of how novel I find it.
Using |> (forward pipe) is helpful for showing the order of executions.
For example, if you want to execute function f, then g like this:
g(f(x))
It's easier to see the order of executions (e.g., f and then g) this way:
x |> f |> g
Programming languages like OCaml or F# are used a lot to transform data from one form to another, so |> can be used that way to show how data got transformed.
let sqr = x => x * x;
[1,2,3]
|> List.map (x => x + 1)
|> List.map (sqr);
The reverse application operator (|>) can simply be defined as
let (|>) x f = f x
This infix operator takes a value x and a function f and apply the latter to the first (f x). This may not seem apparently useful at first, but the operator is powerful when used correctly because functions in Ocaml are curried.
For example, let's say we had a function wackymath: int -> int -> int -> int
let wackymath a b c = a + b - c
The type of wackymath is int -> int -> int -> int. This is because in a functional realm (specifically, lambda calculus), any function only applies to one argument at a time. Therefore, with the help of parentheses, the order of application of wackymath looks like this:
(((wackymath a) b) c)
Argument substitution could make this clearer.
let f1 = wackymath 10;; (* 10 + b - c *)
let f2 = f1 19;; (* 10 + 19 - c *)
f2 4;; (* 10 + 19 - 4 = 25 *)
This could be expressed with the |> operator as such:
4 |> (19 |> (10 |> wackymath));;
Now it's clear why it's called reverse application operator. The parentheses are there because |> is left-associative. Saying |> helps avoid parentheses are not exactly precise in all cases.
Usually the operator is useful in situations when you want to compose a series of sequential function applications
[1; 2; 3; 4; 5]
|> List.map (fun x -> x * 2)
|> List.filter (fun x -> x < 3)
|> fun l -> match l with
| [] -> 0
| l' -> l' |> List.fold_left ~init:0 ~f:(fun a b -> a + b)
;;
So I have this exercise:
filter (fun x -> x = 0) [(1,0);(2,1);(3,0);(4,1)];;
result int list [1;3]
So basically you have to match your x in fun with the second number in list and if its the same you create new list with the first number.
My solution but is wrong
let rec filter f = function
| []->[]
| x::l -> if f=snd x then fst x :: filter f l else [];;
I get the following error when i want to try the code:
Error: This expression has type int but an expression was expected of
type
int -> bool
I can't reproduce the problem you report. Here's what I see when I try your code:
$ ocaml
OCaml version 4.02.1
# let rec filter f = function
| []->[]
| x::l -> if f=snd x then fst x :: filter f l else [] ;;
val filter : 'a -> ('b * 'a) list -> 'b list = <fun>
# filter 0 [(1,0); (2,1); (3,0)];;
- : int list = [1]
There are no errors, but it gets the wrong answer. That's what I would expect looking at your code.
The error that you are getting is saying that somewhere the compiler is expecting an int -> bool function, but you are giving it an int. The reason you get this error is because you have an equality (f = snd x), where f is of type int -> bool and snd x is of type int. both arguments given to the equality must be of the same type. Instead, what you want to do is simply branch on the result of applying f to the second element of x, such as:
let rec filter f = function
| []->[]
| x::l -> if f (snd x) then fst x :: filter f l else [];;
That said, I would recommend using pattern matching instead of fst and snd, such as:
let rec filter f l =
match l with
| [] -> []
| (x,y)::l -> if f y then x :: filter f l else filter f l
Note that f y will return something of type bool, which will then determine which branch to take.
Altough Matts answer is right. It's good to just reuse existing functions instead of writing a special from the ground up:
[(1,0);(2,1);(3,0);(4,1)]
|> List.filter (fun (_, x) -> x = 0)
|> List.map fst
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 ;).