I am reading the book "Professional F# 2.0" The author shows the following code
let a string : option = None
if a.IsNone then
System.Console.WriteLine("a is none")
else
System.Console.WriteLine("a is some");;
then says
"this makes the use of Option vastly superior to the use of null and goes a long way towards removing a significant source of exceptions thrown at runtime"
ok. so I write
System.Console.WriteLine(a.GetType());;
And I get
System.NullReferenceException: Object reference not set to an instance of an object. at System.Object.GetType() at .$FSI_0008.main@() Stopped due to error
And I am like 'un!!!"
How is really doing a
if a.isSome then
do bla bla
any different from
if a != null then
do bla bla
So I don't see how is the programmer being saved from NullPointers
PS: NullPointerException has caused me lot of grief in the past.
The F# compiler does not prevent you from NullReferenceException
completely. When you work with types defined in .NET, then you can still get null
value, because there is no way F# could prevent that.
However, when you work with types declared in F#, then the compiler does not allow creating null
values of that type, and so it avoids NullReferenceException
in that case. For example, the following code does not compile:
type Person(name:string) =
member x.Name = name
// 'Person' is a type declared in F#, so the argument cannot be 'null' in safe code
let printName (person:Person) =
printfn "%s" person.Name
// Compiler error here - 'null' is not a valid value of 'Pereson' type
printName null
When you use option<Person>
as an argument, then you have to explicitly check for None
and Some
cases. This is best done using match
, which checks that you're not missing any of the cases. For example:
let printName (person:option<Person>) =
match person with
// You get a warning here, saying that you're not handling the 'None' case!
| Some person -> printfn "%s" person.Name
The warning tells you that you should add case handling None
. You can still compile the code, but you will not get NullReferenceException
when working with F# types if you do not ignore warnings.
See also this great, related StackOverflow post.
To add to the answer by Tomas, a major benefit of Option
type lies in the higher order functions that it supports, that give you more brevity and safety. You might find my blog post on the topic useful.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With