Skip to content

Instantly share code, notes, and snippets.

@mikehadlow
Created January 25, 2011 23:14
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mikehadlow/795905 to your computer and use it in GitHub Desktop.
Save mikehadlow/795905 to your computer and use it in GitHub Desktop.
The simplest possible Monad in three languages: C#, F# and Haskell
using System;
namespace Suteki.Monads
{
public class FunctionComposition
{
public void AddTwoNumbers()
{
var result =
from a in 3.ToIdentity()
from b in 4.ToIdentity()
select a + b;
Console.Out.WriteLine("result.Value = {0}", result.Value);
}
}
// The simplest possible Monad, Identity
// it does nothing more than contain a value of the given the type
public class Identity<T>
{
public T Value { get; private set; }
public Identity(T value)
{
Value = value;
}
}
public static class IdentityExtensions
{
// These two functions make Identity<T> a Monad.
// a function 'Unit' or 'Return' or 'ToIdentity' that creates a new instance of Identity
public static Identity<T> ToIdentity<T>(this T value)
{
return new Identity<T>(value);
}
// a function 'Bind', that allows us to compose Identity returning functions
public static Identity<B> Bind<A, B>(this Identity<A> a, Func<A, Identity<B>> func)
{
return func(a.Value);
}
// SelectMany is required for Linq syntax
public static Identity<C> SelectMany<A, B, C>(this Identity<A> a, Func<A, Identity<B>> func, Func<A, B, C> select)
{
return select(a.Value, func(a.Value).Value).ToIdentity();
}
}
}
type Identity<'a> = Identity of 'a
let getValue (a : Identity<'a>) = match a with Identity x -> x
let mreturn x = Identity x
let bind (a : Identity<'a>) (f : 'a -> Identity<'b>) = f (getValue a)
type IdentityBuilder() =
member x.Bind(a, f) = bind a f
member x.Return(a) = mreturn a
let identity = new IdentityBuilder()
let result = identity {
let! a = Identity 4
let! b = Identity 3
return a + b
}
printfn "result = %A" (getValue result)
module Main (
main
) where
data Identity a = Identity a
getValue (Identity a) = a
instance Monad Identity where
return a = Identity a
(>>=) a f = f $ getValue a
main = putStrLn $ show $ getValue $ do
a <- Identity 4
b <- Identity 3
return (a + b)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment