7
votes

Can everyone explain to me this piece of code ?

let safe_division n = function
| 0 -> failwith "divide by 0"
| m -> n / m

When I excute safeDiv 3 0 , what is the m and n in this case ?

In general case, when does the function match the first and second pattern ?

4

4 Answers

11
votes

It is easy to see what this means once you realise that

let f x y z = e

is just a short-hand for

let f = function x -> function y -> function z -> e

That is, a function of n arguments actually is n nested functions of 1 argument. That representation is called "currying". It is what allows you to apply a function partially, e.g.

let g = f 3

returns a function of 2 arguments.

Of course, the short-hand above can be mixed freely with the explicit form on the right, and that's what your example does. You can desugar it into:

let safe_division = function n -> function
                                  | 0 -> failwith "divide by 0"
                                  | m -> n / m
10
votes

When you execute safe_division 3 0, first, 3 is bound to the name n and the right-hand side of the declaration is then evaluated.

This is a function, so the next argument, 0, is matched against the different cases, in order. Here, it matches the first case, so the right-hand side is evaluated and an exception is thrown. In this case, the name m is never bound to anything.

If the second argument was, for example, 1, then it would have matched the second case (this case matches every possible value anyway, it's a default case), binding the name m to the value 1 and then returning the result of n / m.

7
votes
let safe_division n 

define a function which type is int -> ...

function
| 0 -> failwith "divide by 0"
| m -> n / m

define a function which type is int -> int

So the resulting type of the whole is int -> int -> int where n is the first argument, and m the second. The last int is the result.

1
votes
let safe_division n = function
| 0 -> failwith "divide by 0"
| m -> n / m

is just equivalent to:

let safe_division n = fun x -> match x with
| 0 -> failwith "divide by 0"
| m -> n / m

Note fun and function are slightly different. See: http://caml.inria.fr/pub/docs/manual-ocaml/expr.html#sec121