import std.stdio; import std.math; //template eltype(X:X[]) { alias X eltype; } // use typeof(X.init[0]) instead // A declaration of X template declare(X) { X declare; } // The return type of a function type FunTy taking 1 argument of type ArgTy template rettype(FunTy,ArgTy) { alias typeof(declare!(FunTy)(ArgTy.init)) rettype; } template map(ArrTy, FunTy) { rettype!(FunTy,typeof(ArrTy.init[0]))[] map(ArrTy arr, FunTy fun) { rettype!(FunTy,typeof(arr[0]))[] ret; ret.length = arr.length; foreach(uint i, typeof(arr[0]) t; arr) ret[i] = fun(t); return ret; } } template filter(ArrTy, FunTy) { ArrTy filter(ArrTy arr, FunTy fun) { ArrTy ret; foreach(typeof(arr[0]) a; arr) if (fun(a)) ret ~= a; return ret; } } void main() { const int[] data = [1,2,3,76,2,1,3,45,2]; writefln("data = ", data); auto squared = map(data, function int(int x) { return x*x; }); writefln("squared = ", squared); auto sqrooted = map(data, function double(int x) { return sqrt(cast(float)x); }); writefln("sqrooted = ", sqrooted); auto even = filter(data, function bool(int x) { return (x&1) == 0; }); writefln("even = ", even); auto odd = filter(data, function bool(int x) { return (x&1) == 1; }); writefln("odd = ", odd); }