Reputation: 1424
I've asked myself a stupid question and have been wracking my brain for a few hours now with no result.
Let's say you want to implement a cons cell in C# for whatever reason (Greenspun's tenth rule should be enough). Since it's in C#, you want it to be statically typed. Something like this should suffice:
interface ICons<T, U>
{
T Left { get; }
U Right { get; }
}
struct Cons<T, U> : ICons<T, U>
{
public T Left { get; }
public U Right { get; }
public Cons(T left, U right)
{
Left = left;
Right = right;
}
}
struct Nil : ICons<Nil, Nil>
{
public Nil Left => this;
public Nil Right => this;
}
Now there's a static void VisitList<T>(? list, Action<T> action)
method that accepts a well-formed list of T
and does something to each element. A well-formed list of T
is a Nil
or a cons cell that has T
as its left element and a well-formed list of T
as its right element. Now we can replace ?
with a real type (yes, imagine there's an Either
not-monad): static void VisitList<T, U>(Either<Nil, ICons<T, U>> list, Action<T> action) where U : Either<Nil, ICons<T, U>>
.
The impossible question is: how the heck do you construct a value that you can pass to this method? Can anyone write a working snippet? The rest of the sample code follows.
class Either<T, U>
{
public bool IsRight { get; }
public bool IsLeft => !IsRight;
public T Left { get; }
public U Right { get; }
public Either(T left)
{
IsRight = false;
Right = default(U);
Left = left;
}
public Either(U right)
{
IsRight = true;
Left = default(T);
Right = right;
}
public static implicit operator Either<T, U>(T value) => new Either<T, U>(value);
public static implicit operator Either<T, U>(U value) => new Either<T, U>(value);
}
class Program
{
static void VisitList<T, U>(Either<Nil, ICons<T, U>> list, Action<T> action)
where U : Either<Nil, ICons<T, U>>
{
while (list.IsRight) {
action(list.Right.Left);
list = list.Right.Right;
}
}
static void Main(string[] args)
{
VisitList(/*put your well-formed cons list here*/, WriteLine);
ReadKey(true);
}
}
Upvotes: 5
Views: 476