Monads in C# … and F#

An elegant example of functional mapping.
You need this framework at the very core of your app, where a light object relational map must be bundled to the model classes.
image

One day you’ll discover that a class in your build method is surprisingly null because a DateTime was fluent mapped to a null field.
Here is the smart extension that does the magic 🙂

public static class NullableExtension
{
public static Tout Maybe <Tin, Tout> (this Tin canBeNull, Func property)
	{
	if (canBeNull == null) {
		return default(Tout);
	}
	return property(canBeNull);
	}
}

And now enjoy its elegant usage!

DateTime JustADate = ANullableDateTime.Maybe(x => x.Value.Date);

Have you noticed the parametric types BTW?

I/O Monad

I’ve recently forked a gist for IO Monad in F#

[<AutoOpen>]
module MaybeIO =

    type MaybeIO<'a> = IO
<option<'a>>

    let run (x: MaybeIO<'a>): 'a option = IO.run x 

    [<RequireQualifiedAccess>]
    module MaybeIOMonad =
        let rtrn x: MaybeIO<'a> = IOMonad.rtrn (Some x)
        let bind f io =
            IOMonad.bind (function
                | Some x -> f x
                | None   -> IOMonad.rtrn(None)) io
        let map f io = bind (f >> rtrn) io
        let liftIO io = IOMonad.map Some io

    type MaybeIOBuilder() =
        member this.Bind(x, f) = MaybeIOMonad.bind f x
        member this.Return(x) = MaybeIOMonad.rtrn x
        member this.ReturnFrom(e): MaybeIO<_> = e

    let maybeIo = new MaybeIOBuilder()

You’ll find a discussion of the role of liftIO in the context of function purity here and here.

Advertisements

One thought on “Monads in C# … and F#

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s