2
votes

Normally, we write a function like this

let abs_diff x y = abs (x-y)

also we can have a curried version:

let abs_diff = fun x -> fun y -> abs(x-y)

I write this question here just want to confirm that I understand currying correctly.

Here is my understanding:

  1. let abs_diff = fun x -> fun y -> abs(x-y) actually returns a function with one parameter which is fun y -> abs (x-y) and inside it, x is the parameter

  2. So, when we apply abs_diff 5 6, it firsts takes the first argument 5, returns a function fun y -> abs (5-y), then continue to apply to argument 6, so the final result is (fun y -> abs (5-y)) 6

Am I correct?

Furthermore, to deal with an function application, is OCaml interpreter like utop, ocaml doing like point 2 above?

2

2 Answers

2
votes

First of all, the two writing

let abs_diff x y = abs (x-y)
let abs_diff = fun x -> fun y -> abs(x-y)

are equivalent. They both define the very same function of type

val abs_diff : int -> int -> int = <fun>

An uncurried version would have been

# let abs_diff (x,y) = abs(x-y);;
val abs_diff : int * int -> int = <fun>

that is a function taking one parameter namely a couple (x,y) of type int*int.


It is not clear to me what you mean by

and inside it, x is the parameter

Do you mean that x is replaced by the parameter ?


What really is happening it that the call to abs_diff 5 return a closure, that is a function with some context. Something like

fun y -> abs (x-y)   where   x = 5

which is of course equivalent to

fun y -> abs (5-y)

Note that the compiler is able to optimize all this function manipulation to a simple function call if this is what you need.

2
votes

Let me add this:

Functions in OCaml are always curried. This can be strange for beginners.The confusion can be: when do I assign the function, and when the function result?

# let sayhello  = print_endline "hello!";;
hello!
val sayhello : unit = ()
# let hello ()  = print_endline "hello!";;
val hello : unit -> unit = <fun>
# let h = hello;;
val h : unit -> unit = <fun>
# h ();;
hello!
- : unit = ()

sayhello is assigned the result of the execution of print_endline, which is ().

hello is a function that takes () as parameter.

h is now the same function, not executed. It is executed if the parameter is there.

I hope I made this clearer. One must definitely learn to perfectly read the type information the toplevel prints out.

One more thing to syntax:

let f1 x y = x - y;;
let f2 = fun x y -> x - y;;
let f3 = function x -> function y -> x - y;;

These definitions result in the same function. You can use fun with more than one parameter, but not function.

Hope this helps.