演算子のオーバーロードを乱用してみた
C# は演算子のオーバーロードの規則が厳しくてつらいことがあるんですけど、回避できるかも!
・・・と思いついて、やってみたら出来なかった、という話です。
やりたいことは関数合成です。
F# の関数合成みたいに、>> とか << で合成できたらわかりやすくていいよなぁ、とか思うんですけど、C# で << とか >> は右項が int に限定されています。
なので、関数が int に暗黙変換できれば解決できるかも?と思ってやってみたんですが、非常に残念な感じになりました。
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace OpOverloadHack { class Program { static void Main(string[] args) { F f = new F(arg => ((int)arg) + 10); F g = new F(arg => ((int)arg) * 2); Console.WriteLine((f >> g)[3]); // (3 + 10) * 2 = 26 Console.WriteLine((f << g)[3]); // (3 * 2) + 10 = 16 } } class F { static readonly IDictionary<int, F> instances = new Dictionary<int, F>(); static int nextId = 0; readonly int id; readonly Func<object, object> call; public F(Func<object, object> f) { this.call = f; this.id = nextId++; instances[this.id] = this; } public object this[object arg] { get { return call(arg); } } public static F operator >> (F f, int id) { var g = instances[id]; return new F(arg => g.call(f.call(arg))); } public static F operator <<(F f, int id) { var g = instances[id]; return new F(arg => f.call(g.call(arg))); } public static implicit operator int(F f) { return f.id; } } }
型情報が保てませんでした・・・
まぁ、もしできたとしてもやるべきではないですけどね。