Reputation: 63
let f (x :: []) = [1;2];;
I don't understand the structure of this function.
Normally a function is declared like this:
let <function name> <arguments> = <function definition>
But here
we give the function f a constant as an argument, namely [x], and then do
nothing with this argument. Instead, we assign the constant [1;2] to the function f?
Upvotes: 0
Views: 107
Reputation: 18912
To illustrate why having patterns in a function definition is useful, here are few examples of exhaustive patterns in arguments. The first common case is tuple:
let f (x,y) = x + y
In the code above,(x,y)
is a pattern that binds the first and second element of a couple to the x
and y
variable respectively.
There is an equivalent construction for records
type vec2 = {x: float; y:float}
let f { x; _ } { y; _ } {x=x'; y = y' } = x +. y +. x' + y'
In this case {x; _}
, {y; _ }
, { x=x'; y=y'}
are both exhaustive patterns.
For ordinary variants, it is less frequent to have useful and exhaustive patterns, but this can happen:
let f (x::_, _ | [], x) = x
Here, in this case we are either extracting the first element of the list in the first element of the tuple if the list is not empty, or the second element of the tuple. Those cases are more frequent when using GADTs or empty types that makes it possible to have some branches of an algebraic not inhabited for a specific subtype. For instance, the pattern in
type empty = |
let f (None:empty option) = ()
is exhaustive because the only possible value of the type empty option
is None
.
Upvotes: 3
Reputation: 36680
utop # let f x :: [] = [1;2];;
Error: Syntax error
This does give me an error. The following will compile.
let f (x :: []) = [1; 2]
But produces a warning about incomplete pattern match, because a list can have zero or any number of elements. A list with one element is just one specific example.
utop # let f (x :: []) = [1; 2];;
Line 1, characters 6-24:
Warning 8 [partial-match]: this pattern-matching is not exhaustive.
Here is an example of a case that is not matched:
_::_::_
val f : 'a list -> int list = <fun>
It's worth noting that [x]
is not a constant in a function like this. It is binding the name x
to the one element in the list, whatever that happens to be.
Consider:
utop # let foo [x] = x;;
Line 1, characters 8-15:
Warning 8 [partial-match]: this pattern-matching is not exhaustive.
Here is an example of a case that is not matched:
_::_::_
val foo : 'a list -> 'a = <fun>
utop # foo [42];;
- : int = 42
Of course, this is a silly function, since x
is never used by the function. You might just have written the following, using _
to indicate a value that we don't care enough about to give a name to.
let foo [_] = [1; 2]
Upvotes: 1