Skip to content

Instantly share code, notes, and snippets.

@bleis-tift
Forked from anonymous/gist:5572563
Last active December 17, 2015 07:28
Show Gist options
  • Save bleis-tift/5572582 to your computer and use it in GitHub Desktop.
Save bleis-tift/5572582 to your computer and use it in GitHub Desktop.
System.Lazyの合成できる版的な
using System;
using System.ComponentModel;
namespace LangExt.Playground
{
public sealed class LazyVal<T>
{
readonly Func<T> f;
bool hasValue = false;
T value;
public LazyVal(Func<T> f) { this.f = f; }
[EditorBrowsable(EditorBrowsableState.Never)]
public bool AlreadyComputed { get { return hasValue; } }
public T Value
{
get
{
if (hasValue) return value;
value = f();
hasValue = true;
return value;
}
}
public static implicit operator T(LazyVal<T> v) { return v.Value; }
public static implicit operator LazyVal<T>(Func<T> f) { return new LazyVal<T>(f); }
}
}
using System;
namespace LangExt.Playground
{
public static partial class LazyVal
{
public static LazyVal<U> Bind<T, U>(this LazyVal<T> self, Func<T, LazyVal<U>> f)
{
return new LazyVal<U>(() => f(self.Value).Value);
}
public static U Map<T, U>(this LazyVal<T> self, Func<T, U> f)
{
return new LazyVal<U>(() => f(self.Value));
}
public static LazyVal<T> OrElse<T>(this LazyVal<T> self, LazyVal<T> v)
{
if (self.AlreadyComputed) return self;
else return v;
}
public static LazyVal<T> Unwrap<T>(this LazyVal<LazyVal<T>> self)
{
return self.Value;
}
}
}
using System;
using System.ComponentModel;
namespace LangExt.Playground
{
partial class LazyVal
{
[EditorBrowsable(EditorBrowsableState.Never)]
public static U Select<T, U>(this LazyVal<T> self, Func<T, U> f)
{
return self.Map(f);
}
[EditorBrowsable(EditorBrowsableState.Never)]
public static LazyVal<V> SelectMany<T, U, V>(this LazyVal<T> self, Func<T, LazyVal<U>> f, Func<T, U, V> g)
{
return self.Bind(t => f(t).Bind(u => new LazyVal<V>(() => g(t, u))));
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment