-
-
Save kiwidev/2806a6b67ca2b29c2198 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
namespace Immutable | |
{ | |
enum Qux { Qux1, Qux2 } | |
static class Option | |
{ | |
public static Option<T> Value<T>(T value) | |
{ | |
return new Option<T>(value); | |
} | |
} | |
struct Option<T> | |
{ | |
public static readonly Option<T> None = new Option(); | |
private readonly bool _hasValue; | |
private readonly T _value; | |
public Option(T value) | |
{ | |
_hasValue = true; | |
_value = value; | |
} | |
public T Value | |
{ | |
get { return _value; } | |
} | |
public bool HasValue | |
{ | |
get { return _hasValue; } | |
} | |
public T ValueOrDefault(T defaultValue) | |
{ | |
return _hasValue ? _value : defaultValue; | |
} | |
} | |
class Baz | |
{ | |
public Baz(Qux qux) | |
{ | |
Qux = qux; | |
} | |
public Qux Qux { get; } | |
} | |
class Bar | |
{ | |
public Bar(Baz baz) | |
{ | |
Baz = baz; | |
} | |
public Baz Baz { get; } | |
} | |
class Foo | |
{ | |
public Foo(Bar bar) | |
{ | |
Bar = bar; | |
} | |
public Bar Bar { get; } | |
} | |
static class Extensions | |
{ | |
public static Foo With(this Foo foo, Option<Bar> bar = default(Option<Bar>)) => new Foo(bar.ValueOrDefault(foo.Bar)); | |
public static Bar With(this Bar bar, Option<Bar> baz = default(Option<Baz>)) => new Bar(baz.ValueOrDefault(bar.Baz)); | |
public static Baz With(this Baz baz, Option<Qux> qux = default(Option<Qux>)) => new Baz(qux.ValueOrDefault(baz.Qux)); | |
public static Foo With(this Foo foo, Func<Bar, Bar> bar = null) => new Foo(bar != null ? bar(foo.Bar) : foo.Bar); | |
public static Bar With(this Bar bar, Func<Baz, Baz> baz = null) => new Bar(baz != null ? baz(foo.Baz) : bar.Baz); | |
public static Baz With(this Baz baz, Func<Qux, Qux> qux = null) => new Baz(qux != null ? qux(foo.Qux) : baz.Qux); | |
} | |
static class Program | |
{ | |
private static Foo SetQux(Foo foo, Qux qux) => foo.With(Option.Value(foo.Bar.With(Option.Value(foo.Bar.Baz.With(Option.Value(qux)))))); | |
private static Foo SetQuxAlternate(Foo foo, Qux qux) => foo.With(bar => bar.With(baz => baz.With(Option.Value(qux))); | |
public static void Main() | |
{ | |
var it = new Foo(new Bar(new Baz(Qux.Qux1))); | |
Console.WriteLine(it.Bar.Baz.Qux); | |
var newIt = SetQux(it, Qux.Qux2); | |
Console.WriteLine(newIt.Bar.Baz.Qux); | |
var newIt2 = SetQuxAlternate(it, Qux.Qux2); | |
Console.WriteLine(newIt.Bar.Baz.Qux); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment