As LarsJo said, using tuples makes it very easy to use pattern-matching.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
 

type Person = Person of string * (string * string) option

let f person =
  do 
    match person with
    | Person (name, Some (father, mother)) -> 
        print_string (name + "'s mother is " + mother + " and his/her father is " + father)
    | Person (name, None) ->
        print_string (name + " has no known parents")
  print_string "\n"

//or equivalently
let f' (Person (name, parents)) =
  do 
    match parents with
    | Some (father, mother) ->
        print_string (name + "'s mother is " + mother + " and his/her father is " + father)
    | None ->
        print_string (name + " has no known parents")
  print_string "\n"

let people=[Person("Adam",None);
            Person("Eve",None);
            Person("Cain",Some("Adam","Eve"));
            Person("Abel",Some("Adam","Eve"))]

people |> List.iter f
people |> List.iter f'
;;

With regards to options, they are not meant to be customized data structures (as records) but they are useful for dual cases such as initialized/not initialized, or a function that returns a warning or no warning, or a result or no result, in monadic expressions etc.

For extracting them, you can use pattern-matching as in the above example :

1
match x with Some v -> ... | None -> ...

or like so :

1
let f x = if x <> None then print_string (any_to_string (Option.get x))

Hope this helps

By on 4/1/2008 4:48 AM ()

Hi Julien,

very helpful!

Thank you

By on 4/1/2008 5:54 AM ()

Lets say you have any element of the list, called "myElement". If you want to grab the "option" part, you use a "pattern match" like this:

1
let (namePart, optionPart) = myElement

That isn't too much more work than a record...and you didn't actually have to DEFINE a record type in order to represent just two items.

Typically, however, when you do pattern matches, however, you use a pattern "match" statement:

1
2
3
4
match myElement with
|  (someName, None) -> <doStuff with someName> 
| ("Cain", Some("Adam", b) ) -> <do Stuff with b>
| (aName, Some(a,b) ) -> <do Stuff with aName, a, and b

Pattern matching is very powerful...and it is very easy when you use the "(, ,...)" syntax.

It is sometimes easier/prettier to do pattern-matching without records (but it is still possible with records), so that is why you might not want to use a record. Combining records with "Active Patterns" (see Expert F#) is a very nice combo.

By on 3/31/2008 12:34 PM ()
IntelliFactory Offices Copyright (c) 2011-2012 IntelliFactory. All rights reserved.
Home | Products | Consulting | Trainings | Blogs | Jobs | Contact Us | Terms of Use | Privacy Policy | Cookie Policy
Built with WebSharper