Skip to content

Instantly share code, notes, and snippets.

@j0057
Created March 6, 2013 07:32
Show Gist options
  • Save j0057/5097428 to your computer and use it in GitHub Desktop.
Save j0057/5097428 to your computer and use it in GitHub Desktop.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FunWithMonads
{
static class Program
{
/*
* Nullable<T>
*/
static Nullable<T> SimpleNullable<T>(T item)
where T : struct
{
return new Nullable<T>(item);
}
static Nullable<int> AddOne_1(Nullable<int> nullable)
{
if (nullable.HasValue)
{
return SimpleNullable(nullable.Value + 1);
}
else
{
return new Nullable<int>();
}
}
static Nullable<R> ApplyFunction<A, R>(Nullable<A> nullable, Func<A, R> function)
where A : struct
where R : struct
{
if (nullable.HasValue)
{
return SimpleNullable(function(nullable.Value));
}
else
{
return new Nullable<R>();
}
}
public static Nullable<R> Bind<A, R>(this Nullable<A> nullable, Func<A, Nullable<R>> function)
where A : struct
where R : struct
{
return nullable.HasValue
? function(nullable.Value)
: null;
}
static Nullable<int> AddOne_2(Nullable<int> nullable)
{
return ApplyFunction(nullable, (int value) => value + 1);
}
static Nullable<double> DivideByTwo(Nullable<int> nullable)
{
return ApplyFunction(nullable, (int value) => value / 2.0);
}
static Nullable<double> DivideByTwo_2(Nullable<int> nullable)
{
return nullable.Bind<int, double>((int value) => value / 2.0);
}
/*
* OnDemand<T> == Func<T>
*/
delegate T OnDemand<T>();
static OnDemand<T> SimpleOnDemand<T>(T item)
{
return () => item;
}
static OnDemand<int> AddOne_1(OnDemand<int> onDemand)
{
return () => onDemand() + 1;
}
static OnDemand<R> ApplyFunction<A, R>(OnDemand<A> onDemand, Func<A, R> function)
{
return () => function(onDemand());
}
static OnDemand<int> AddOne_2(OnDemand<int> onDemand)
{
return ApplyFunction(onDemand, (int unwrapped) => unwrapped + 1);
}
/*
* Lazy<T>
*/
static Lazy<T> SimpleLazy<T>(T item)
{
return new Lazy<T>(() => item);
}
static Lazy<int> AddOne_1(Lazy<int> lazy)
{
return new Lazy<int>(() => lazy.Value + 1);
}
static Lazy<R> ApplyFunction<A, R>(Lazy<A> lazy, Func<A, R> function)
{
return new Lazy<R>(() => function(lazy.Value));
}
static Lazy<int> AddOne_2(Lazy<int> lazy)
{
return ApplyFunction(lazy, (int unwrapped) => unwrapped + 1);
}
/*
* Task<T>
*/
static Task<T> SimpleTask<T>(T item)
{
return new Task<T>(() => item);
}
static Task<int> AddOne_1(Task<int> task)
{
return task.ContinueWith<int>(t => t.Result + 1);
}
static Task<R> ApplyFunction<A, R>(Task<A> task, Func<A, R> function)
{
return task.ContinueWith(t => function(t.Result));
}
static Task<int> AddOne_2(Task<int> task)
{
return ApplyFunction(task, (int unwrapped) => unwrapped + 1);
}
/*
* IEnumerable<T>
*/
static IEnumerable<T> SimpleEnumerable<T>(T item)
{
yield return item;
}
static IEnumerable<int> AddOne_1(IEnumerable<int> items)
{
foreach (int unwrapped in items)
{
yield return unwrapped + 1;
}
}
static IEnumerable<R> ApplyFunction<A, R>(IEnumerable<A> items, Func<A, R> function)
{
foreach (A unwrapped in items)
{
yield return function(unwrapped);
}
}
static IEnumerable<int> AddOne_2(IEnumerable<int> items)
{
return ApplyFunction(items, (int unwrapped) => unwrapped + 1);
}
/*
* Prove it
*/
static void Main(string[] args)
{
Nullable<int> nullable = 41;
OnDemand<int> onDemand = () => 2;
Lazy<int> lazy = new Lazy<int>(() => 3);
Task<int> task = new Task<int>(() => 4);
IEnumerable<int> sequence = new int[] { 5 };
var aa_1 = AddOne_1(nullable);
var aa_1_ = aa_1.Value;
var aa_2 = AddOne_2(nullable);
var aa_2_ = aa_2.Value;
var aa_3 = DivideByTwo(nullable);
var aa_3_ = aa_3.Value;
var bb_1 = AddOne_1(onDemand);
var bb_1_ = bb_1();
var bb_2 = AddOne_2(onDemand);
var bb_2_ = bb_2();
var cc_1 = AddOne_1(lazy);
var cc_1_ = cc_1.Value;
var cc_2 = AddOne_2(lazy);
var cc_2_ = cc_2.Value;
//task.Start();
var dd_1 = AddOne_1(task);
var dd_1_ = dd_1.Result;
var dd_2 = AddOne_2(task);
var dd_2_ = dd_2.Result;
var ee_1 = AddOne_1(sequence);
var ee_1_ = ee_1.ToArray();
var ee_2 = AddOne_2(sequence);
var ee_2_ = ee_2.ToArray();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment