let rec
map2 (f : 'a * 'b -> 'c) (l1 : 'a list) (l2 : 'b list) : 'c list =
match (l1,l2) with
| ([], []) -> []
| (x::l1),(y::l2) -> f (x, y)::(map2 f (l1, l2))
It is returning:
Error: This expression has type 'a list * 'a list
but an expression was expected of type 'a list
What am I doing wrong here??
The error is map2 f (l1, l2) (as the error location would have told you). You're passing (l1, l2) as a tuple while they should be separate curried parameters : map2 f l1 l2.
Also, your function does not handle the cases of different length (patterns with one list empty but not the other). In this case, the function will raise a match failure, you may want to raise a more specialized error such as invalid_arg "map2" or something.
Related
I would like to print a meaningful message when raising a defined exception in OCaml:
type t = A | B of int
exception Wrong of t
Say I have a function
let string_of_t = function
| A -> "A"
| B n -> ("B" ^ (string_of_int n))
Then I would like to have a function
val print_exception : ( 'a -> string ) -> a' exn -> string
so that I can define
let my_raise e =
print_endline ("Error: I got the unexpected value" ^ (print_exception string_of_t e));
raise e [???]
Is there such a function print_exception ?
The problem is not very well-posed (for instance, there is no a' exn type), but I hope my intent is understandable. I've seen that one can use [##deriving sexp] but this looks like some magic outside of the language, and there is probably something easier and within the language.
There are two ways. The first one is using Printexc, the second one would be to match all the exceptions you want to print and print accordingly, something like:
exception Zero of int
exception B of string
let pp ppf = function
| Zero d -> Format.fprintf ppf "Zero of %d" d
| B s -> Format.fprintf ppf "B of %s" s
| Not_found -> Format.fprintf ppf "Not found"
| _ -> Format.fprintf ppf "Your exception is in another castle"
let f n d = if d = 0 then raise (Zero d) else n / d
let () =
let n, d = (10, 0) in
try Format.printf "%d/%d is %d#." n d (f n d)
with e ->
Format.eprintf "%a#." pp e;
Format.eprintf "%s#." (Printexc.to_string e)
Will give
❯ ./exc
Zero of 0
Exc.Zero(0)
Combining the two seems to be the best solution to be able to customise some displays and let all the others be a default one:
let pp ppf = function
| Zero d -> Format.fprintf ppf "Zero of %d" d
| e -> Format.fprintf ppf "%s" (Printexc.to_string e)
In OCaml we don't have (yet) modular implicits so unless you use [##derive ...] you need to use one of the two solutions.
As a side-note, exceptions can be caught in a pattern matching:
let () =
let n, d = (10, 0) in
match f n d with
| r -> Format.printf "%d/%d is %d#." n d r
| exception e ->
Format.eprintf "%a#." pp e;
Format.eprintf "%s#." (Printexc.to_string e)
It does semantically the same as what I wrote before but it's better for call stacks (if I'm not mistaken)
[EDIT] Looks like I forgot a third solution, see #octachron's answer
If you want to log a meaningful message before raising, it seems to me that it might be simpler to combine the logging and exception raising in one function rather than trying to reconstruct an error message from a generic unknown exception after the fact. For instance, the following function
let log_and_raise exn fmt =
Format.kfprintf
(fun ppf -> Format.pp_print_newline ppf (); raise exn)
Format.err_formatter fmt
can be used like this
exception A of int
let test n = log_and_raise (A n) "Raising the exception (A %d)" n
and will raise the exception A n after printing the error message on stderr.
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 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)
# 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) ;;