Composition of functions with several arguments

Hi,

If

f : 'a -> 'b -> ... -> 'z

and

g : 'z -> 'aa

I would like to define the composition

h = Fun.compose g f

so that h takes exactly the same arguments as f but returns a value of type 'aa, but this does not work when f has more than one argument.

Of course I can write

let h a b c d ... y = let z = f a b c d ... y in g z

but this is tedious. Is there another way? If not, is there a (deep?) reason for this?

let f x _ = x

Do we get a two argument function?

magic_compose succ (f : 'a -> 'b -> 'a)

Or a three argument function?

magic_compose succ (f : (int -> int) -> 'b -> int -> int)

I don’t see your point, in your example f takes 2 arguments so you cannot compose it on the right by succ

In my question g has only one argument so the composition g • f is mathematically well defined

ok, now you have edited your post to put succ on the left, but then there is no ambiguity, since

f : 'a -> 'b -> 'a

and

succ : int -> int

then the composition is valid only if 'a = int and then

succ • f : int -> 'b -> int

The point is we get different results by using a type constraint, and OCaml semantics are type-independent.

oh I see, the fact that 'b -> int -> int is treated the same as 'b -> (int -> int) makes this impossible. Too bad. Thanks for the explanation

Hello @sanette,

Probably you are looking for the “mathematical composition”, and probably you already know about the operators |> and @@ (both are in Pervasives). However as you mentioned just:

let h a b c d ... y = let z = f a b c d ... y in g z

I note that you have always these two other ways to create an effective composition (or a chain of compositions):

let k a b c d  = (f a b c d ) |> g |> h 

and

let k a b c d  = h @@ g @@ (f a b c d )

For example this should work and both functions k and m are well defined:

let f x y z  = (x+y, x+z)
let g (x,y) = x+y 
let h x = (x, 2*x) 
let k x y z =  (f x y z ) |> g |> h
let m x y z =  h @@ g @@ (f x y z) 

both k and m should be

int -> int -> int -> int*int = <fun>

and they give the expected value.

Thanks for your message, yes I like the |> operator too. My question was rather whether you could avoid repeating all the arguments of the fonction