Here is an answer similar to the one @hvd provided, but using the Y
operator defined here, this removes the need for the local variables:
public static Func<A, R> Y<A, R>(Func<Func<A, R>, Func<A, R>> f)
{
return t => f(Y(f))(t);
}
var halves = Y<double, IEnumerable<double>>(self => d => new[] { 0d }.SelectMany(_ => new[] { d }.Concat(self(d / 2))));
An example use would be:
foreach (var half in halves(20))
Console.WriteLine(half);
Which would output 20, 10, 5, 2.5 etc...
I wouldn't advise using this in production code but it is fun.
The Y
operator also allows other recursive lambda expressions, e.g:
var fibonacci = Y<int, int>(self => n => n > 1 ? self(n - 1) + self(n - 2) : n);
var factorial = Y<int, int>(self => n => n > 1 ? n * self(n - 1) : n);
var hanoi = Y<int, int>(self => n => n == 1 ? 1 : 2 * self(n - 1) + 1);
yield
return
. – Upturnedi=>x/Math.Pow(2, i)
for whatever x is your starting element. – Aquinas1
, as in the example. An inexact representation of some other fraction, such as1d/3
, will keep the same imprecision (percentage-wise) each time you halve the value (because you're dealing with a power of 2). Division by 2 means decrementing the bits representing the exponent; bits representing the "significand" are unchanged. When you get to denormalized values, division by two is a right bit shift, and you risk losing precision. en.wikipedia.org/wiki/Double-precision_floating-point_format if you're interested in the details. – Regin