Is this functional code? Dr.T. Reply.

-

This would be a func­tional ap­proach:

CountWithPrevious : [‘a] => (a => a => bool) => int // type of the function
CountWithPrevious [] _                    = 0
CountWithPrevious [_]  _                  = 0
CountWithPrevious [prev, val | tail] pred = CountWithPrevious [val | tail] + (pred val prev ? 1 : 0)

Some ob­ser­va­tions:

_” is used as wild­card ar­gu­ment — matches any value that you don’t need a name for. [ x,y,z | t ] are pat­tern match­ing over lists — here x,y and z get bound to the first el­e­ments and t is the rest of the list. Both CountWithPrevious and the passed-in pred are cur­ried — they take two ar­gu­ments but one at a time. The CountWithPrevious func­tion is de­fined with pat­tern match­ing — at run­time it searches through the de­f­i­n­i­tions un­til one matches. The type de­c­la­ra­tion is op­tional — the com­piler can fig­ure out the type from the last case of the func­tion. In C# we don’t have pat­tern match­ing and cur­ry­ing, and so would prob­a­bly need a helper func­tion.

public static int CountWithPrevious<T>(IEnumerable<T> en, PredWithPrevious pred) {
IEnumerator<T> rest = en.GetEnumerator();

if (rest.MoveNext()) return Helper(rest.Current,rest,pred);

else return 0;

}

private static int Helper<T>(T prev, IEnumerator<T> rest, PredWithPrevious pred) {

if (rest.MoveNext()) {

T val = rest.Current;

return Helper(val,rest,pred) + (pred(val,prev) ? 1 : 0);

} else return 0;

}

We could simulate local functions with lambdas so that we don’t need to pass pred, prev and T along:

public static int CountWithPrevious<T>(IEnumerable<T> en, PredWithPrevious pred) {
IEnumerator<T> rest = en.GetEnumerator();

Func<T,int> helper = prev => {

if (rest.MoveNext()) {

T val = rest.Current;

return Helper(val) + (pred(val,prev) ? 1 : 0);

} else return 0;

};

if (rest.MoveNext()) return Helper(rest.Current);

else return 0;

}

Tags

1 Comment

Comments

Charlie Calvert's Community Bl

2007-02-02T02:52:36Z

Welcome to the twen­ti­eth Community Convergence. I’m Charlie Calvert, the C# Community PM, and this is