I need to make function that split lazy list. For example, [5;6;3;2;1] -> [5;3;1] and [6;2]. Here is syntax of regular lists, but it have to be lazy. Function split by index, odd to first list, even to second. I write function like this, but I don`t know how to add to lazy list new element:
let rec merge list =
let rec mergeHelp list acc = function
| LNil -> failwith "Empty list"
| LCons(x, xf) ->
if (acc mod 2 == 0)
then LCons(x, function() -> mergeHelp (acc+1) (xf())), LCons(LNil, function() -> LNil)
else LCons(LNil, function() -> LNil), LCons(x, function() -> mergeHelp (acc+1) (xf()))
in mergeHelp list 0
;;
I don’t know what your lazy list type is but I’m going to assume from your code it looks like:
type 'a t = LNil | LCons of 'a * (unit -> 'a t)
Note that this is different from a more typical lazy list where (unit -> 'a t) would be 'a t lazy.
Chances are that the two lists won’t be consumed in the same way they are generated and we won’t want to scan through the input running all the functions once for the odds and again for the evens. So let’s write a function to pair up elements:
let rec pair = function
| LNil -> LNil
| LCons (fst, rest) ->
match rest () with
| LNil -> LCons ((fst, None), const LNil)
| LCons (snd, rest) ->
let later_pairs = lazy (pair rest()) in
LCons ((fst, Some snd), fun () -> Lazy.force later_pairs)
This function has type 'a t -> ('a * 'a option) t and the key feature that once you have scanned it once, it is cheap to scan again as you do not recommits the elements of the output. The types are a little bit sad because really we are only allowed None for the second element in the last element of the result but let us live with that and carry on. First we need some trivial utilities:
let rec map f = function
| LNil -> LNil
| LCons (a, r) -> LCons (f a, fun () -> map f (r ()))
let rec filter_map f = function
| LNil -> LNil
| LCons (x, r) ->
let r () = filter_map f (r ()) in
match f x with
| None -> r ()
| Some a -> LCons (a, r)
These have types ('a -> 'b) -> 'a t -> 'b t and ('a -> 'b option) -> 'a t -> 'b t and do the least stupid thing one would guess from reading the type signature. We can now implement the function that does what you want:
let unmerge xs =
let pairs = pair xs in
(map (fun (a,_) -> a) pairs, filter_map (fun (_,b) -> b) pairs)
Related
I want to write a function that returns the longest prefix of a list, where applying a function to every item in that prefix produces a strictly ascending list.
For example:
longestAscendingPrefix (`mod` 5) [1..10] == [1,2,3,4]
longestAscendingPrefix odd [1,4,2,6,8,9,3,2,1] == [1]
longestAscendingPrefix :: Ord b => (a -> b) -> [a] -> [a]
longestAscendingPrefix _ [] = []
longestAscendingPrefix f (x:xs) = takeWhile (\y z -> f y <= f z) (x:xs)
This code snippet produces the error message in the title. It seems the problem lies within that lambda function.
takeWhile has type takeWhile :: (a -> Bool) -> [a] -> [a]. The first parameter is thus a function that maps an element of the list to a Bool. Your lambda expression has type Ord b => a -> a -> Bool, which does not make much sense.
You can work with explicit recursion with:
longestAscendingPrefix :: Ord b => (a -> b) -> [a] -> [a]
longestAscendingPrefix f = go
where go [] = []
go [x] = …
go (x1:x2:xs) = …
where you need to fill in the … parts the last one makes a recursive call to go.
This is a homework. I know I shouldn't ask this here but explanation would be welcomed. :)
My code looks like that:
let some_function f x = match x with
| (k, v) -> fun k -> f k
f should be a function and x is a list of tuples.
My compiler (?) says it's
('a -> 'b) -> 'c * 'd -> 'a -> 'b but it should be ('a -> 'b) -> 'a * 'b -> 'a -> 'b
You don't need to tell me the solution just explain me why it's 'c * 'd and not 'a * 'b
First off, when you write this:
let some_function f x = match x with
| (k, v) -> fun k -> f k
You can pattern match directly in the function arguments.
let some_function f (k, v) =
fun k -> f k
Secondly, the v is never used, so let's get red of that by using _.
let some_function f (k, _) =
fun k -> f k
This does exactly the same thing and gives us something easier to reason about.
However, the k in fun k -> f k shadows the k in the tuple argument to the function, so you're not really using that one either.
So we really have:
let some_function f (_, _) =
fun k -> f k
The concrete types of these are not known, so f is inferred to be a function that takes a value of type 'a and returns a value of type 'b. Therefore f is 'a -> 'b.
That tuple that you never use? It has a type, but we can't know anything about those types from the rest of the function, so the inferred type is 'c * 'd.
We can simplify this one step further. fun k -> f k is equivalent to just writing f, so your function can be equivalently rewritten:
let some_function f (_, _) = f
Though this doesn't allow OCaml to infer that f is a function, so the type signature becomes:
'a -> 'b * 'c -> 'a
I was wondering how to write my own sortOn function.
I made a sortBy function and an on function as shown bellow but can't figure out how to combine them and what additional code to add. sortOn is like sortBy but the given function (in here named comp) is applied only once for every element of the list
sortBy :: (a -> a -> Ordering) -> [a] -> [a]
sortBy comp [] = []
sortBy comp [x] = [x]
sortBy comp (x:xs) = insert x (sortBy comp xs)
where
insert x [] = [x]
insert x (y:ys)
| (comp x y == LT) || (comp x y == EQ) = x:y:ys
| otherwise = y:(insert x ys)
on :: (b -> b -> c) -> (a -> b) -> a -> a -> c
on b f x y = b (f x) (f y)
Here's a hint.
If you have a list [a] and you just sort it, the sort function will implicitly make use of the Ord instance for a and specifically the function:
compare :: a -> a -> Ordering
to figure out the relative ordering of pairs of a elements.
Now, if you have a list [a] and a transformation function b, and you want to use sortOn to sort the list of the transformed values, you'll need to figure out the relative ordering of pairs of b elements. How will you do this? Well, you'll implicitly use the Ord instance for b and specifically the function:
compare :: b -> b -> Ordering
In other words, when you try to define:
sortOn :: (Ord b) => (a -> b) -> [a] -> [a]
sortOn f lst = ...
you'll have arguments of type:
f :: a -> b
lst :: [a]
and additional objects of type:
sortBy :: (a -> a -> Ordering) -> [a] -> [a]
on :: (b -> b -> c) -> (a -> b) -> a -> a -> c
compare :: b -> b -> Ordering
Now, can you see how to put them together to define sortOn?
SPOILERS
Further hint: What's the type of compare `on` f?
Further further hint: It's a -> a -> Ordering.
# let rec map1 f l = match l with
[]->[]
|h::t -> f h::map1 f t;;
val map1 : ('a -> 'b) -> 'a list -> 'b list = <fun>
I am new to OCaml , I have two questions:
In the third line, why there is a f before h :: map1 f t? f should be a argument in the map1 function. Why the book's example puts it seperately?
In the first example ('a -> 'b) -> 'a list -> 'b list = <fun> why there is a b list?
the book explains that b list is the result of the function f and a list is the argument of the function f. However, why there is no a, b list in the following example? It also has a function f and it also puts f separately in the third line.
# let rec apply f n x=
if n = 0 then x
else f ( apply f (n-1) x);;
val apply : ('a -> 'a) -> int -> 'a -> 'a = <fun>
|h::t -> f h::map1 f t
the precedence rules of Ocaml's syntax means that the above match clause is parsed as
|h::t -> (f h)::(map1 f t)
and of course f h is the application of function f to argument h
In words, when the list l is matching the pattern h::t (so l is a proper list of head h and tail t), a pair is made :: (or built, or constructed) of head f h and tail map1 f t
A typical use would be first to have a function from integers to strings:
let nextasstr n = Printf.sprintf "(%d)" (n+1);;
So nextasstr 2 is the string "(3)" without the quotes. Of course [2;3] is a list of integers, i.e. a int list
Then map1 nextasstr [2;3] is evaluated to [ "(3)"; "(4)" ], a list of strings, i.e. a string list; you see that the second argument has a type different of the result. (this should give an insight on the 'a list vs 'b list difference and the typing map1 : ('a -> 'b) -> 'a list -> 'b list) with the first argument being a arbitrary function of type 'a -> 'b
You should see the Ocaml MOOC, follow the Ocaml tutorial, read its documentations. This may take weeks of work.
I have to write the function try_finalyze f g y x of type : ('a -> 'b) -> ('b -> 'c) -> 'c -> 'a -> 'c
knowing that:
1. if an exception is raised by f x the returned value has to be y
2. if f x doesn't raise any exception we have to return the result of g applied on f x
exception E
let try_finalyze f g y x = try g (f x) with E -> y;;
val try_finalyze : ('a -> 'b) -> ('b -> 'c) -> 'c -> 'a -> 'c = <fun>
1.Is it right how I treated the problem?
2.In this context what will do the following function:
fun f -> try_finalyze f (fun x-> Some x) None
I don't see the role of a function like (fun x-> Some x)
The answer to your first question is - not really. According to your specification function should catch any exception, not only your exception E. Maybe I'm misreading, but it will be better use the following definition:
let try_finalize f g y x = try g (f x) with exn -> y
As for the second part of the question, there're several ways in OCaml to signal an error. The two most common are:
Raise an exception
Return a value of an option type
The former variant is syntactically lighter, the later doesn't allow a caller to ignore the error condition. Sometimes you need to switch from one variant to an another. Suppose you have a function that raises an exception, and you would like to create a function with the same behavior, but returning an option value. Let's give it a name:
let with_option f = try_finalize f (fun x-> Some x) None
Then we can, for example, convert a List.hd to a function that returns an option type, depending on whether the list is empty or not:
let head x = with_option List.hd x
This function will have type 'a list -> 'a option, compare it with List.hd type 'a list -> 'a, the former will not allow to ignore the empty list case. When applied to an empty list, it will return a None value:
# head [];;
- : 'a option = None
If you write
let try_finalize f g y x = try g (f x) with _ -> y
Your function will return y if f doesn't raise an error but g does, which is not what you said you want.
To ensure that you catch only errors from f you should put f x alone in the try block:
let try_finalize f g y x =
let z = try Some (f x) with _ -> None in
match z with
| Some z -> g z
| None -> y
Exceptions may be considered bad style in a purely functional code, that's why you may want to transform a function that may raise an exception such as List.assoc : 'a -> ('a * 'b) list -> 'b into a function that does the same thing but returns an option.
That's what
let with_option f = try_finalize f (fun x-> Some x) None
does.
If I understand the problem statement correctly, I think I would do this :
let try_finalize f g y x =
try
let v = f x in g v
with _ -> y
As for question 2, suppose you have a function f that takes a value of type v and computes a result of type r. This :
fun f -> try_finalize f (fun x-> Some x) None
returns a function that tries to apply f. If it succeeds (i.e. no exception is thrown), it returns Some r. Otherwise, it returns None. Basically, it transforms a function that may throw an exception into a function that will not throw anything. The new function returns a r option instead of a r.
Maybe like this but the function doesn't have anymore the required type
let try_finalyze f g y x = match f x with
|E -> y
| _ -> g (f x) ;;