リスト実装した
C#でリストを実装した。System.Collections.Generic.Listとは別物だよ!
畳み込みを使って階乗を求める。
namespace ListTest { class Program { static void Main(string[] args) { Console.WriteLine("10! = {0}", List<int>.FoldLeft<int>( (a, b) => a * b, 1, List<int>.FromArray(Enumerable.Range(1, 10).ToArray()) ) ); } } }
自然数の3乗のリスト
namespace ListTest { class Program { static void Main(string[] args) { Console.WriteLine("{0}", List<int>.Map( n => n * n * n, List<int>.FromArray(Enumerable.Range(1, 20).ToArray()) ).ToString() ); } } }
ソース(幾つかの関数については動作未確認)
using System; using System.Linq; namespace Functional { public class List<T> { static public List<T> Empty = null; private T hd; private List<T> tl; public T Hd { get { return hd; } } public List<T> Tl { get { return tl; } } public List(T hd, List<T> tl) { this.hd = hd; this.tl = tl; } static public List<T> Cons(T hd, List<T> tl) { return new List<T>(hd, tl); } static public int Length(List<T> l) { Func<List<T>, int, int> length = null; length = (lst, len) => { if (lst == Empty) return 0; else return length(lst.Tl, len + 1); }; return length(l, 0); } static public T Nth(List<T> l, int n) { if (l == Empty) throw new ArgumentException("リストが短すぎます。"); else if (n == 0) return l.Hd; else return Nth(l.Tl, n - 1); } static public List<T> Reverse(List<T> l) { Func<List<T>, List<T>, List<T>> reverse = null; reverse = (l1, l2) => { if (l1 == Empty) return l2; else return reverse(l1.Tl, Cons(l1.Hd, l2)); }; return reverse(l, Empty); } static public List<T> Append(List<T> l1, List<T> l2) { if (l1 == Empty) return l2; else return Cons(l1.Hd, Append(l1.Tl, l2)); } static public List<T> ReverseAppend(List<T> l1, List<T> l2) { if (l1 == Empty) return l2; else return ReverseAppend(l1.Tl, List<T>.Cons(l1.Hd, l2)); } static public List<T> Concat(List<List<T>> l) { if (l == List<List<T>>.Empty) return Empty; else return Append(l.Hd, Concat(l.Tl)); } static public void Iter(Action<T> f, List<T> l) { if (l == Empty) return; else { f(l.Hd); Iter(f, l.Tl); } } static public List<T> Map(Func<T, T> f, List<T> l) { if (l == Empty) return l; else return Cons(f(l.Hd), Map(f, l.Tl)); } static public List<T> ReverseMap(Func<T, T> f, List<T> l) { Func<List<T>, List<T>, List<T>> reversemap = null; reversemap = (l1, l2) => { if (l1 == Empty) return l2; else return reversemap(l1.Tl, Cons(f(l1.Hd), l2)); }; return reversemap(l, Empty); } static public A FoldLeft<A>(Func<A, T, A> f, A e, List<T> l) { if (l == Empty) return e; else return FoldLeft(f, f(e, l.Hd), l.Tl); } static public B FoldRight<B>(Func<T, B, B> f, List<T> l, B e) { if (l == Empty) return e; else return f(l.Hd, FoldRight(f, l.Tl, e)); } // ユーティリティ static public List<T> FromArray(T[] arr) { List<T> l = Empty; arr.Reverse(); for (int i = 0; i < arr.Length; ++i) l = Cons(arr[i], l); return l; } public override string ToString() { Func<List<T>, string, string> tostring = null; tostring = (l, s) => { if (l.Tl == Empty) return s + l.Hd.ToString() + "]"; else return tostring(l.Tl, s + l.Hd.ToString() + "; "); }; return "[" + tostring(this, ""); } } }