Composition of function pair - functional-programming

I am very new to OCaml and I am currently trying to solve some exercises. While doing so I stumbled over the following problem:
let compose_pair (p:(('b -> 'c) * ('a -> 'b))) : 'a -> 'c =
The goal is to complete the function such that it composes the two functions of the pair in sequence.
My problem is that, as far as I understand, the return type of this function should again be a function and I don't really know how to achieve that.
My attempt would be something like
(fst p) (snd p)
which happens to just return something of type 'c if I understood this right.
Does anyone know how to solve this? i would be very thankful for some tips or hints.
My current try is this:
let compose_pair (p:(('b -> 'c) * ('a -> 'b))) : 'a -> 'c =
fun x -> fst p (snd p x)

You are writing a function that takes a pair:
fun pair -> ...
and returns a function, which takes some value:
fun pair -> (fun value -> ...)
The return value in the inner function is the composition of the functions stored in the pair.

Your function, as quoted below, appears to work quite well.
let compose_pair (p:(('b -> 'c) * ('a -> 'b))) : 'a -> 'c =
fun x -> fst p (snd p x)
# let compose_pair (p:(('b -> 'c) * ('a -> 'b))) : 'a -> 'c =
fun x -> fst p (snd p x) ;;
val compose_pair : ('b -> 'c) * ('a -> 'b) -> 'a -> 'c = <fun>
# let f = compose_pair ((fun x -> x + 1), (fun x -> x * 2));;
val f : int -> int = <fun>
# f 3;;
- : int = 7
However, it can be cleaned up. You can pattern match a tuple argument to a function directly, rather than calling fst and snd.
let compose_pair (f, g) = ...
You can then produce a function which takes an argument and applies it to these functions.
let compose_pair (f, g) =
fun x -> f (g x)
But we can simplify this further, because let f a b c = ... is the same as writing let f = fun a -> fun b -> fun c -> ....
let compose_pair (f, g) x = f (g x)
Or as an alternative, using the |> operator.
let compose_pair (f, g) x = x |> g |> f

Related

Combine a list of functions into a single function using fold

Lets say I have a list of functions
let plus_one (x: int) : int = x + 1 in
let double (x: int) : int = x * 2 in
let square (x: int) : int = x * x in
let fun_list = [square, double, plus_one] ;;
Using fold, I want to take this list of functions and combine them into a single function. Something like,
let combined (x: int) : int = x * (2 * (x + 1))
This is what I have:
let combine_functions (fun_list : ('a -> 'a) list) : ('a -> 'a) =
List.fold_right (fun f acc -> f acc) fun_list (fun x -> x)
;;
I would think this would work, however when I try to run this, it tells me that this expression has type 'a -> 'a when it should have type ('a -> 'a) -> ('a -> 'a)
I've solved this by changing the second line of code from
List.fold_right (fun f acc -> f acc) fun_list (fun x -> x)
to
List.fold_right (fun f acc -> (fun x -> f (acc x))) fun_list (fun x -> x)
I'm a bit unclear on what sort of combination you want, do you mean functional composition? If that's the case, then your combined function would look something like this:
square (double (plus_one x))
or
((x + 1) * 2) * ((x + 1) * 2)
which could be achieved by the function
let combine_functions ls =
List.fold_right (fun f x -> f x) ls;;
However I'm not totally sure if this is really what you're trying to do. As an aside, you don't need to explicitly type all your OCaml code, and I personally find that I'm more productive when I let the type inference do it for me.

What information does this statement reveal about the function f in SML?

(*function f's definition*)
fun f l j y = l j y
val f = fn : ('a -> 'b -> 'c) -> 'a -> 'b -> 'c
What does the below line say about the function f ?
val f = fn : ('a -> 'b -> 'c) -> 'a -> 'b -> 'c
To answer this question it helps to rename your identifiers:
fun apply g x y = g x y;
val apply = fn : ('a -> 'b -> 'c) -> 'a -> 'b -> 'c
apply is equivalent to what you are calling f. What apply does, informally, is take a function, g, of two variables (in curried form) and two arguments x,y and actually applies g to those arguments.
As an example g, define:
fun sum x y = x + y;
val sum = fn : int -> int -> int
Then, for example:
apply sum 5 7;
val it = 12 : int
In the type signature of apply the part
('a -> 'b -> 'c)
is the type of g. It is polymorphic. You can apply any function to arguments of an appropriate type. When you actually use apply (as I did above with sum) then the SML compiler will have enough information to figure out what concrete types correspond to the type variables 'a, 'b, 'c. the overall type of apply is
('a -> 'b -> 'c) -> 'a -> 'b -> 'c
which says that apply is a function which, when fed a function of type ('a -> 'b -> 'c) and arguments of type 'a and 'b, produces a result of type 'c. I'm not sure of any immediate use of apply, though it does serve to emphasize the perspective that functional application is itself a higher-order function.

OCaml Explicit polymorphic type annotations

I would enjoy to receive some helpful comments concerning an example given on:
http://caml.inria.fr/pub/docs/manual-ocaml-400/manual021.html#toc79
7.12 Explicit polymorphic type annotations
type 'a t = Leaf of 'a | Node of ('a * 'a) t
let rec depth : 'a. 'a t -> 'b = function
|Leaf _ -> 1
| Node x -> 1 + depth x
I understand this example function, but when I try to define a 'map-like' function of type
'a. 'a t -> ('a -> 'b) -> 'b t
e.g.:
let rec tmap: 'a. 'a t ->(f:'a->'b) -> 'b t = function
|Leaf x -> Leaf( f x)
|Node x -> let res = tmap x in Node(res);;
I get the following error:
Characters 67-77:
|Leaf x -> Leaf( f x)
^^^^^^^^^^
Error: This expression has type 'c t but an expression was expected of type
(f:'a -> 'b) -> 'b t
which I do not completely understand.
I would appreciate any helpful comment.
You forgot to get the second argument.
let rec tmap:
'a. 'a t ->(f:'a->'b) -> 'b t = (* asking for two arguments *)
function (* takes only the first argument *)
|Leaf x -> Leaf( f x)
|Node x -> let res = tmap x in Node(res);;
Also, 'b must be polymorphic too, as you want to generate nested tuples as long as you descend through the tree.
This should be, thanks to ivg:
let rec tmap : 'a 'b. 'a t -> f:('a->'b) -> 'b t = fun t ~f ->
match t with
|Leaf x -> Leaf( f x)
|Node x -> let f (a,b) = (f a, f b) in Node ( tmap x ~f ) ;;
You have a few problems, like improperly placed parenthesis around f, forgotten argument to the tmap function in the Node branch, and you've forget the quantifier for 'b. So, finally, with the help of PatJ we can write the following:
type 'a t = Leaf of 'a | Node of ('a * 'a) t
let rec depth : 'a. 'a t -> 'b = function
| Leaf _ -> 1
| Node x -> 1 + depth x
let rec tmap: 'a 'b. 'a t -> f:('a -> 'b) -> 'b t =
fun t ~f -> match t with
| Leaf x -> Leaf (f x)
| Node x ->
Node (tmap ~f:(fun (x,y) -> f x, f y) x)
tmap (Node (Leaf (7,8))) ~f:(fun x -> x + 1, x + 2);;
- : (int * int) t = Node (Leaf ((8, 9), (9, 10)))
many thanks for your great help.
Now my test cases work out as intended:
let int_tree = Node(Node(Leaf((3,-1),(0,4))));;
let char_tree = Node(Node(Leaf(('a','c'),('d','c'))));;
tmap int_tree ~f:(fun x -> x*x);;
- : int t = Node (Node (Leaf ((9, 1), (0, 16))))
tmap char_tree ~f:(fun x -> Char.uppercase x);;
- : char t = Node (Node (Leaf (('A', 'C'), ('D', 'C'))))

How to memoize recursive functions?

Consider a recursive function, say the Euclid algorithm defined by:
let rec gcd a b =
let (q, r) = (a / b, a mod b) in
if r = 0 then b else gcd b r
(This is a simplified, very brittle definition.) How to memoize such a function? The classical approach of defining a high-order function memoize : ('a -> 'b) -> ('a -> 'b)
adding memoization to the function is here useless, because it will only save time on the first call.
I have found details on how to memoize such function in Lisp or Haskell:
How do I memoize a recursive function in Lisp?
Memoization with recursion
These suggestions rely on the ability found in Lisp to overwrite the symbol definition of a function or on the “call-by-need” strategy used by Haskell, and are therefore useless in OCaml.
The winning strategy is to define the recursive function to be memoized in a continuation passing style:
let gcd_cont k (a,b) =
let (q, r) = (a / b, a mod b) in
if r = 0 then b else k (b,r)
Instead of defining recursively the gcd_cont function, we add an argument, the “continuation” to be called in lieu of recursing. Now we define two higher-order functions, call and memo which operate on functions having a continuation argument. The first function, call is defined as:
let call f =
let rec g x =
f g x
in
g
It builds a function g which does nothing special but calls f. The second function memo builds a function g implementing memoization:
let memo f =
let table = ref [] in
let compute k x =
let y = f k x in
table := (x,y) :: !table; y
in
let rec g x =
try List.assoc x !table
with Not_found -> compute g x
in
g
These functions have the following signatures.
val call : (('a -> 'b) -> 'a -> 'b) -> 'a -> 'b = <fun>
val memo : (('a -> 'b) -> 'a -> 'b) -> 'a -> 'b = <fun>
Now we define two versions of the gcd function, the first one without memoization and the second one with memoization:
let gcd_call a b =
call gcd_cont (a,b)
let gcd_memo a b =
memo gcd_cont (a,b)
# let memoize f =
let table = Hashtbl.Poly.create () in
(fun x ->
match Hashtbl.find table x with
| Some y -> y
| None ->
let y = f x in
Hashtbl.add_exn table ~key:x ~data:y;
y
);;
val memoize : ('a -> 'b) -> 'a -> 'b = <fun>
# let memo_rec f_norec x =
let fref = ref (fun _ -> assert false) in
let f = memoize (fun x -> f_norec !fref x) in
fref := f;
f x
;;
val memo_rec : (('a -> 'b) -> 'a -> 'b) -> 'a -> 'b = <fun>
You should read the section here: https://realworldocaml.org/v1/en/html/imperative-programming-1.html#memoization-and-dynamic-programming in the book Real World OCaml.
It will help you truly understand how memo is working.

OCaml recursive calls can't have different type parameters?

Is there a way to have a recursive call but with different type parameters?
Here's an example which I think should compile, but doesn't.
let swap (a, b) = (b, a)
module Test : sig
val test : bool option ->
('a -> 'b -> 'c) * ('b -> 'a -> 'c)
-> 'a -> 'b -> 'c
end = struct
let rec test (b : bool option)
(f : ('a -> 'b -> 'c) * ('b -> 'a -> 'c))
(x : 'a) (y : 'b) : 'c =
match b with
| None -> (fst f) x y
| Some true -> (test None f x y)
| Some false -> (test None (swap f) y x)
end
The compiler insists that 'a and 'b must be the same type in test even though there's no reason for it. Is this a bug?
This is actually an very interesting question.
I didn't know the answer before, but by reading through the two answers before me, plus a bit research, I will try explain and answer below.
Basically, what you want to achieve is the signature like this
val test : bool option -> ('a -> 'b -> 'c) * ('b -> 'a -> 'c) -> 'a -> 'b -> 'c
First of all, I have to emphasise that trying to force the parameters to be different polymorphic types, i.e., use 'a, 'b, 'c etc, will not necessarily force OCaml compiler to think that the parameters must have different types.
for example, if you do
let f (x:'a) (y:'b) = x + y;;
It seems you are forcing x and y to be different types, but after compiling, it gives
val f : int -> int -> int = < fun >
Basically, OCaml will anyway do its type inference, and apply the conclusion if it is not just against the forced type.
You may think the 'a and 'b in let f (x:'a) (y:'b) = x + y;; to be maybe x and y will have different types and also possibly same types. So it is pointless to force types of parameters like that, right?
So, let's remove all the types forced on parameters and we get
let rec test b f x y =
match b with
| None -> (fst f) x y
| Some true -> test None f x y
| Some false -> test None (swap f) y x
The type of test will be given by OCaml like this:
val test : bool option -> ('a -> 'a -> 'b) * ('a -> 'a -> 'b) -> 'a ->
'a -> 'b = < fun >
So, basically, OCaml thinks x and y must have the same types, and c is not there because the next available type tag for OCaml to use is 'b.
Why x and y must have same types?
When OCaml meets let rec test b f x y, ok, it will think x has type of 'a and y has type of 'b'.
When OCaml meets | Some true -> test None f x y, no problem, the above type inference still stand because you are pass same x and y to test again.
The the funny part is when OCaml meets | Some false -> test None (swap f) y x. You are trying pass y and x (notice the order) to test. In order to let test work, x and y must have the same type, right?
Basically, above is what the counter side of polymorphism recursion #Jeffrey Scofield answered.
polymorphism recursion means, a function can have some parameters whose types can be changed during recursion, instead of stay constant.
OCaml by default of course only allow constant parameter types.
So how does rank 2 polymorphism work?
So how to solve it?
You need a for_all type 'a.. have a look at my question: In OCaml, what type definition is this: 'a. unit -> 'a.
If we use 'a. or 'a 'b. in type definition, then it means it is really for all types, real polymorphic types, and please, ocaml, do not narrow them down as long as it does not harm.
let rec test : 'a 'b. bool option -> ('a -> 'b -> 'c) * ('b -> 'a -> 'c) -> 'a -> 'b -> 'c =
fun b f x y ->
match b with
| None -> (fst f) x y
| Some true -> test None f x y
| Some false -> test None (swap f) y x
Above is the new version of test.
You force type with 'a 'b. for the function test and for 'a and 'b, ocaml will think they are really both polymorphic, and thus the parameter x and y can be accepted in both orders.
You're asking for polymorphic recursion, for which type inference is undecidable in the general case: Wikipedia on Polymorphic Recursion. So I don't think it's a bug.
I think there are ways to get what you want using rank-2 polymorphism.
I think it's a bug because if you create a new function (identical to the first one), then the type is correct:
# let rec t b f x y = match b with
| true -> (fst f) x y
| false -> u true (swap f) y x
and u b f x y = match b with
| true -> (fst f) x y
| false -> t true (swap f) y x;;
val t : bool -> ('a -> 'b -> 'c) * ('b -> 'a -> 'c) -> 'a -> 'b -> 'c = <fun>
val u : bool -> ('a -> 'b -> 'c) * ('b -> 'a -> 'c) -> 'a -> 'b -> 'c = <fun>
using OCaml 4.01.0:
module rec Test : sig
val test : bool option -> ('a -> 'b -> 'c) * ('b -> 'a -> 'c) -> 'a -> 'b -> 'c
end = struct
let rec test b f x y =
match b with
| None -> (fst f) x y
| Some true -> (Test.test None f x y)
| Some false -> (Test.test None (swap f) y x)
end;;
See the section on Recursive modules.
Small example as a test case:
let add_float_int x y = x +. (float y);;
let add_int_float x y = add_float_int y x;;
let adds = add_float_int, add_int_float;;
List.map (fun x -> Test.test x adds 10 10.) [None; Some true; Some false];;

Resources