The function aux only has one param n. Why can it accept list at the bottom?
# let length list =
let rec aux n = function
| [] -> n
| _ :: t -> aux (n + 1) t
in
aux 0 list;;
val length : 'a list -> int = <fun>
The function aux only has one param n. Why can it accept list at the bottom?
# let length list =
let rec aux n = function
| [] -> n
| _ :: t -> aux (n + 1) t
in
aux 0 list;;
val length : 'a list -> int = <fun>
The function keyword introduces a function which takes a single argument, which it pattern matches.
This is equivalent to:
let length lst =
let rec aux n lst =
match lst with
| [] -> n
| _ :: t -> aux (n + 1) t
in
aux 0 lst
Or...
let length lst =
let rec aux n =
fun lst ->
match lst with
| [] -> n
| _ :: t -> aux (n + 1) t
in
aux 0 lst
The function expression produces a function of one argument.
# function [] -> 0 | _ -> 1;;
- : 'a list -> int = <fun>
Now, if you write a function f that takes a parameter n, and whose body contains function, as follows:
# let f n = function [] -> 0 | _ -> n;;
val f : int -> 'a list -> int = <fun>
Then f is a function that takes n and returns a function of a single argument.
# f 3;;
- : '_weak1 list -> int = <fun>
The returned value is a function that takes a list of some unknown type of values, and returns an integer (the _weak prefix is related to Weak Type Variables, this is not important here).
Since the returned value is a function, you can apply it:
# (f 3) ["test"];;
- : int = 3
You can drop the parentheses around f 3 because that's how function application is grouped by default:
# f 3 ["test"];;
- : int = 3
So what looks like a function taking two arguments is in fact a function taking one argument, evaluating to a function to which we apply the second argument.
(See also Currying)
function keyword will match the last argument, even it’s not declared in the left side of =.
Compare with match .. with, the match needs the argument name show up.