This would be a functional approach:
CountWithPrevious : [‘a] => (a => a => bool) => int // type of the functionCountWithPrevious [] _ = 0CountWithPrevious [_] _ = 0CountWithPrevious [prev, val | tail] pred = CountWithPrevious [val | tail] + (pred val prev ? 1 : 0)
Some observations:
In C# we don’t have pattern matching and currying, and so would probably need a helper function.
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; }