F# Option int Example: IsNone, IsSome and ValueLearn about option types. Access the IsNone, IsSome and Value properties on an option.
Option. Some things exist. Some things do not. A computer runs programs. A space elevator takes no passengers. An option expresses existence.
A discriminated union. This is similar to a Nullable in C#. It can have a value (like an int) or be None. It is an optional int: a value that might not exist.
Let us begin. Many built-in functions like List.tryFindIndex return options. This function uses a predicate (a lambda) and returns the first index where an element matches.
Here: The "result" is an option int. We cannot use it as an int directly—we must extract its Value.
Some: When we print an option int to the screen, we see the type name "Some." If the inner value is 2, we see "Some 2."Printfn
IsNone, IsSome: These will return true if the option is None or is Some. Often we use these in if-statements.if, elif
Value: For the inner value of the discriminated union, we access the Value property. This must be done only if the option is not None.
F# program that uses option, IsNone, IsSome, Value
// An example list.
let ids = [10; 20; 30]
// Find index of element with value 30.
// ... This returns an option int.
let result = List.tryFindIndex (fun y -> y = 30) ids
// Write return value.
printfn "Result = %A" result
printfn "IsNone = %A" result.IsNone
printfn "IsSome = %A" result.IsSome
// See if there is a value.
if result.IsSome then
// Get and write the value.
let num = result.Value
printfn "Value = %A" num
Result = Some 2
IsNone = false
IsSome = true
Value = 2
Here we examine how to create a discriminated union (an option) from a function. In checkNumber we receive one argument, and return None or a Some value based on that argument.Match
Result: When we pass the argument 0 to checkNumber, we get None back. We test this with an if.
Next: We pass 1 to checkNumber and get Some number back. We use IsSome to test it, and then print its value.
F# program that uses None and Some
// If number is 0, return None.
// ... Otherwise return Some number.
let checkNumber n = match n with
| 0 -> None
| _ -> Some(n)
// This returns None.
let c = checkNumber 0
if c = None then
printfn "None returned"
// This returns Some number.
let n = checkNumber 1
if n.IsSome then
printfn "Some returned, value = %A" n.Value
Some returned, value = 1
An error. We cannot use an option as we would use the underlying value. An error will occur. We must access IsSome and Value on the result of tryFindIndex.
F# program that causes error
// This returns an option int, not an int.
let index = List.tryFindIndex (fun y -> y = 10) [2; 10; 12]
// We must access the Value, not just use the option.
let result = index + 1
error FS0001: The type 'int' does not match the type 'int option'
An option is similar to a Nullable, but not the same. At a high level, though, we see discriminated unions as wrappers for values that can add a "nothing" or null value.
Quote: In F#, the type option is similar to some uses of System.Nullable. For various technical reasons the two types cannot be equated (F# Language Specification).
A review. Options eliminate the need to have special values mean "no value." For example, using None instead of -1 to mean "nothing found" may be clearer. Options help clarify our code.
© 2007-2020 Sam Allen. Every person is special and unique. Send bug reports to email@example.com.