jeroldhaas
6/29/2016 - 4:33 PM

language-ext Option vs FSharpOption construction

language-ext Option vs FSharpOption construction

using LanguageExt;
using static LanguageExt.Prelude;

///////////////////////////////////////////////////////////////////////////////////
// Option<T> doesn't allow null use at all, and it's a struct, so any references
// also can't be null.

string noValue = null;
Option<string> str1 = noValue;            // Implicitly coerced to None
Option<string> str2 = Optional(noValue);  // Explicitly coerced to None
Option<string> str3 = None;               // None
Option<string> str4 = Some(noValue);      // ValueIsNullException is thrown
Option<string> str5 = Some("Hello");      // Some of "Hello"
Option<string> str6 = Optional("Hello");  // Some of "Hello"

///////////////////////////////////////////////////////////////////////////////////
// Matching return values are also checked for null
var str = Some("Hello, World");
var res = match(str,
             Some: x  => noValue,
             None: () => noValue);       // ResultIsNullException is thrown

///////////////////////////////////////////////////////////////////////////////////
// For the rare occasions where you want an optional value that can represent
// null, there is OptionUnsafe<T>.  
             
OptionUnsafe<string> unsstr1 = None;                   // None
OptionUnsafe<string> unsstr2 = SomeUnsafe(noValue);    // Some(null)

///////////////////////////////////////////////////////////////////////////////////
// LanguageExt Option<T> doesn't allow access to a Value property, the only way of 
// getting at the value is via Match, Map, Bind, Iter, Fold, Sum, Filter, Exists,
// ForAll, ... all of which take the state of the discriminated union into account.

///////////////////////////////////////////////////////////////////////////////////
// FSharpOption<T> allows access to the underlying .Value property, which makes it
// fundamentally unsafe, and pretty much pointless (for use in C#).  You may as well 
// use a reference for all the safety it gives you.

var someValue = FSharpOption<string>.Some("Hello");
var noneValue = FSharpOption<string>.None;             // noneValue == null

Console.WriteLine(someValue.Value);
Console.WriteLine(noneValue.Value);                   // This will throw a NullReferenceException

///////////////////////////////////////////////////////////////////////////////////
// language-ext provides conversion functions for F# types to make 
// interop simple:

var someValue = FSharpOption<string>.Some("Hello");

// Convert from FSharpOption<T> to Option<T>
Option<string> opt = fs(someValue);

// Convert back to FSharpOption<T> from Option<T>
FSharpOption<string> fsopt = fs(opt);