Java で higher kinded polymorphism を実現する の C# 版。
ということなので、試しに C# で書いてみました。キャストしようというのが具体的に何を指してるのか良く分からないけれど。
.NET なら F* があるじゃんと思ったんですが、これ MS Research の成果物のくせに .NET 系の言語吐けないんですねなんでやねん…CLR の制限あるし仕方ないか。
Java 版とは違い、highj と同じ、App を TypeConstructor が継承する作法。とりあえず Option クラスを実装してみました。C# 書くの久しぶりだなあ。
namespace higherKinded {
public interface App<F, A> { }
public abstract class Option<A> : App<Option.Type, A> {
public abstract R fold<R>(Func<R> none, Func<A, R> some);
}
public static class Option {
public sealed class Type { }
public static Option<A> some<A>(A value) { return new Some<A>(value); }
public static Option<A> none<A>() { return new None<A>(); }
public static Option<A> narrow<A>(App<Option<A>.Type, A> app) {
return (Option<A>)app;
}
}
public sealed class Some<A> : Option<A> {
public Some(A a) { value = a; }
public A value { get; }
public override R fold<R>(Func<R> none, Func<A, R> some) {
return some(value);
}
}
public sealed class None<A> : Option<A> {
public override R fold<R>(Func<R> none, Func<A, R> some) {
return none();
}
}
}
ということで、当たり前なんですが C# でもできました。めでたしめでたし。まあ Java で出来るんだから大体できる。
ところで roslyn の issue に Higher Kinded Polymorphism / Generics on Generics なんてものがあります。issue 作られたのは去年の四月だし、CLR の制限もあるので、あまり入りそうにはないですが…