Wooga.Lambda


Working with Maybe

"The Maybe type encapsulates an optional value. A value of type Maybe 'T either contains a value of type 'T, or it is empty." - Haskell documentation

The Maybe type in Wooga.Lambda borrows its name from Haskell: The empty Maybe case is called Nothing and the Maybe holding a value is called Just.

Maybe instance

Create a Maybe by injecting a value with Maybe.Just('T) or create the empty one with Maybe.Nothing<'T>().

1: 
2: 
Maybe<string> justAnX = Maybe.Just("x");
Maybe<string> nothing = Maybe.Nothing<string>();

Use the FromMaybe('T) or FromJustOrDefault('T2,'T->'T2) functions to extract the Just value; both will fallback to the given default value in case of Nothing.

1: 
2: 
3: 
4: 
5: 
string ofJustAnX = justAnX.FromMaybe("not x"); // "x"
string ofNothing = nothing.FromMaybe("not x"); // "not x"

int ofJustAnX2 = justAnX.FromJustOrDefault(0, s => s.Length); // 1
int ofNothing2 = nothing.FromJustOrDefault(0, s => s.Length); // 0

Check out the API Reference for more information.

Avoiding null and NullReferenceExceptions

Avoid using null to represent empty values. The following snippet is valid code and will raise a NullReferenceException.

1: 
2: 
string name = null;
int letters = name.Length;

By using Maybe you make sure that the potential empty case will be handled at runtime.

1: 
2: 
Maybe<string> name = Maybe.Nothing<string>();
int letters = name.FromJustOrDefault(0, s => s.Length);

Composing Maybe

Because Maybe is a monad, composing multiple of them is very straightforward. The monadic operators >>= & >> are implemented as Maybe.Bind and Maybe.Then.

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
13: 
14: 
15: 
16: 
17: 
18: 
19: 
Maybe<string> FirstOf(string[] xs)
{
    return xs.Length > 0 ? Maybe.Just(xs[0]) : Maybe.Nothing<string>();
}

Maybe<string> StartsWithA(string s)
{
    return s.StartsWith("A") ? Maybe.Just(s) : Maybe.Nothing<string>();
}

Maybe<string> AtLeast5Chars(string s)
{
    return s.Length >= 5 ? Maybe.Just(s) : Maybe.Nothing<string>();
}

var letters = FirstOf(names)
              .Bind(StartsWithA)
              .Bind(AtLeast5Chars)
              .FromJustOrDefault(0,s => s.Length);
Fork me on GitHub