Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I use pattern matching in 'let' definitions?

I've just noticed F# allows me to use let bindings with literals and other patterns as follows:

let fib 0 = 1
let exists item [] = false
let car (hd :: tl) = hd
let cdr (hd :: tl) = tl

F# correctly interprets these functions as a kind of pattern matching, because gives me the following warnings:

Warning 1 Incomplete pattern matches on this expression. For example, the value '1' will not be matched

Warning 2 Incomplete pattern matches on this expression. For example, the value '[_]' will not be matched

etc.

These functions work as expected, but I want to define a function in this style with complete pattern matches, however I can't find anything about this alternative pattern matching syntax in the F# manual.

I know I can use let whatever = function ... and let whatever x = match x with ... to get the results I want, but I've just discovered yet another syntax for pattern matching and it'll nag at me forever if I don't figure out how to use it.

How do I write functions using the alternative pattern matching syntax shown above?

like image 423
Juliet Avatar asked Jan 18 '09 17:01

Juliet


2 Answers

AFAIK, there is no way in F# to declare multiple let bindings with the same name and different pattern matching signatures. I believe the closest construct to what you are looking for is a function rules expression.

Take this example for car

let car = function
    | hd::tl -> hd
    | [] -> failwith "empty list"
like image 158
JaredPar Avatar answered Oct 13 '22 19:10

JaredPar


JaredPar is right, F# doesn't have the syntactic form that Haskell does here.

The F# form is mostly useful for breaking open single-case discriminated unions or for defining functions with incomplete matches (like your 'car' example that fails on the empty list). It's simply a consequence of the fact that practically all name-binding in the language is done via patterns; this syntactic form (defining a function using patterns on arguments) is not often too useful in practice, for the exact reason you described.

I think Haskell did a number of things better than ML when it comes to syntactic forms, but F#'s roots are in ML. The benefit is that a good subset of F# cross-compiles with OCaml (which helped bootstrap the F# language and user community); the drawback is that F# is 'stuck' with a few bits of ugly/limited syntax.

like image 20
Brian Avatar answered Oct 13 '22 20:10

Brian