F Sharp Programming/Option Types

From Wikibooks, open books for an open world
Jump to navigation Jump to search
Previous: Higher Order Functions Index Next: Tuples and Records
F# : Option Types

An option type can hold two possible values: Some(x) or None. Option types are frequently used to represent optional values in calculations, or to indicate whether a particular computation has succeeded or failed.

Using Option Types[edit]

Let's say we have a function that divides two integers. Normally, we'd write the function as follows:

let div x y = x / y

This function works just fine, but it's not safe: it's possible to pass an invalid value into this function which results in a runtime error. Here is a demonstration in fsi:

> let div x y = x / y;;

val div : int -> int -> int

> div 10 5;;
val it : int = 2

> div 10 0;;
System.DivideByZeroException: Attempted to divide by zero.
   at <StartupCode$FSI_0035>.$FSI_0035._main()
stopped due to error

div 10 5 executes just fine, but div 10 0 throws a division by zero exception.

Using option types, we can return Some(value) on a successful calculation, or None if the calculation fails:

> let safediv x y =
    match y with
    | 0 -> None
    | _ -> Some(x/y);;

val safediv : int -> int -> int option

> safediv 10 5;;
val it : int option = Some 2

> safediv 10 0;;
val it : int option = None

Notice an important difference between our div and safediv functions:

val div : int -> int -> int
val safediv : int -> int -> int option

div returns an int, while safediv returns an int option. Since our safediv function returns a different data type, it informs clients of our function that the application has entered an invalid state.

Option types are conceptually similar to nullable types in languages like C#, however F# option types do not use the CLR System.Nullable<T> representation in IL due to differences in semantics.

Pattern Matching Option Types[edit]

Pattern matching option types is as easy as creating them: the same syntax used to declare an option type is used to match option types:

> let isFortyTwo = function
    | Some(42) -> true
    | Some(_) | None -> false;;

val isFortyTwo : int option -> bool

> isFortyTwo (Some(43));;
val it : bool = false

> isFortyTwo (Some(42));;
val it : bool = true

> isFortyTwo None;;
val it : bool = false

Other Functions in the Option Module[edit]

val get : 'a option -> 'a

Returns the value of a Some option.

val isNone : 'a option -> bool

Returns true for a None option, false otherwise.

val isSome : 'a option -> bool

Returns true for a Some option, false otherwise.

val map : ('a -> 'b) -> 'a option -> 'b option

Given None, returns None. Given Some(x), returns Some(f x), where f is the given mapping function.

val iter : ('a -> unit) -> 'a option -> unit

Applies the given function to the value of a Some option, does nothing otherwise.
Previous: Higher Order Functions Index Next: Tuples and Records