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