Archive for the ‘Ocaml’ Category

Curried Function and labeled arguments in Ocaml

In mathematics, computer science and linguistics (semantics), currying or Schönfinkelisation[1] is the technique of transforming a function that takes multiple arguments into a function that takes a single argument (the other arguments having been specified by the curry). The technique was named by Christopher Strachey after logician Haskell Curry, though it was invented by Moses Schönfinkel and Gottlob Frege.

Wikipedia – curried function.


# let op f x y = (f) x y;;
val op : ('a -> 'b -> 'c) -> 'a -> 'b -> 'c = 

# let add = op (+);;
val add : int -> int -> int =

# let minus = op (-);;
val minus : int -> int -> int =

# let inc = add 1;;
val inc : int -> int 

When you carried a function, you must carried the next not curried argument, but you can swap the arguments or use labeled arguments.


# let flip f x y = f y x;;
val flip : ('a -> 'b -> 'c) -> 'b -> 'a -> 'c = 

# let dec = flip minus 1;;
val dec : int -> int =

# inc 5;;
- : int = 6

# dec 5;;
- : int = 4

# inc (dec 5);;
- : int = 5

The above code swap the arguments, the code belows use labeled arguments.


#  let op2 ~f ~x ~y = (f) ~x ~y;;
val op2 : f:(x:'a -> y:'b -> 'c) -> x:'a -> y:'b -> 'c = 

# let minus2 = op (-);;
val minus2 : int -> int -> int =

# let minus2 = op2 (-);;
val minus2 :  f:(x:'a -> y:'b -> (int -> int -> int) -> 'c) -> x:'a -> y:'b -> 'c =

# let dec2 = minus2 ~y:1;;
val dec2 : f:(x:'a -> y:int -> (int -> int -> int) -> 'b) -> x:'a -> 'b =

# dec 2;;
- : int = 1

Also we can use high order function to curried another function and reuse our code.


# let rec iter f list = match list with
     | [] -> []
     | head::tail -> f head :: iter f tail;;
val iter : ('a -> 'b) -> 'a list -> 'b list = 

# let inc = (+) 1;;
val inc : int -> int =

# let dec x = x-1;;
val dec : int -> int =

# let double x = x * 2;;
val double : int -> int =

# let double_each = iter double;;
val double_each : int list -> int list =

# let inc_each = iter inc;;
val inc_each : int list -> int list =

# let dec_each = iter dec;;
val dec_each : int list -> int list =

# double_each [1;2;3];;
- : int list = [2; 4; 6]

# inc_each [1;2;3];;
- : int list = [2; 3; 4]

# dec_each [1;2;3];;
- : int list = [0; 1; 2]