function upon function in OCaml Confusion about the books's example (beginner) - function

# 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.

Related

OCaml type inference does not yield expected type for function arguments

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

How to preserve the input to a mapA

How does the following work? Given a list of items [a] and a function mapping a to g b, how do I preserve the input in the resulting list?
[a] -> (a -> g b) -> g [(a,b)]
Concretely, I have a list of contract ids. I want to map every contract id to the tuple of (id, payload), where payload is some contract variable. And g b in the above example is fetch.
It's a bit easier if you flip the argument order, then you can do:
mapAWithArgs : Applicative m => (a -> m b) -> [a] -> m [(a, b)]
mapAWithArgs f = mapA (withArg f)
where
withArg f x = (x,) <$> f x
Then you can do withIds <- mapAWithArgs fetch <list of contract IDs> in your Update

Exceptions handling in OCaml

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) ;;

OCaml: Function input ('a * 'b -> 'c)

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.

OCaml: Currying without defined values

I have two functions f and g and I am trying to return f(g(x)) but I do not know the value of x and I am not really sure how to go about this.
A more concrete example: if I have functions f = x + 1 and g = x * 2 and I am trying to return f(g(x)) I should get a function equal to (x*2) + 1
It looks like you have it right, f(g(x)) should work fine. I'm not sure why you have a return keyword there (it's not a keyword in ocaml). Here is a correct version,
let compose f g x = f (g x)
The type definition for this is,
val compose : ('b -> 'c) -> ('a -> 'b) -> 'a -> 'c = <fun>
Each, 'a,'b,'c are abstract types; we don't care what they are, they just need to be consistent in the definition (so, the domain of g must be in the range of f).
let x_plus_x_plus_1 = compose (fun x -> x + 1) (fun x -> x * 2)