CSharp · Console
using System;
using System.Collections.Generic;
using System.Linq;
class LazyList<T>
{
private readonly IEnumerable<T> _enumerable;
public LazyList(IEnumerable<T> enumerable)
{
_enumerable = enumerable;
}
public LazyList<TOut> Bind<TOut>(Func<T, LazyList<TOut>> f)
{
return new LazyList<TOut>(_enumerable.SelectMany(x => f(x)._enumerable));
}
public LazyList<T> Where(Func<T, bool> predicate)
{
return new LazyList<T>(_enumerable.Where(predicate));
}
public LazyList<TOut> Select<TOut>(Func<T, TOut> f)
{
return new LazyList<TOut>(_enumerable.Select(f));
}
public LazyList<TOut> SelectMany<TOut>(Func<T, LazyList<TOut>> f)
{
return Bind(f);
}
public LazyList<TJoin> SelectMany<TMid, TJoin>(
Func<T, LazyList<TMid>> bind,
Func<T, TMid, TJoin> project)
{
return new LazyList<TJoin>(
_enumerable.SelectMany(
x => bind(x)._enumerable.Select(y => project(x, y))
)
);
}
public static LazyList<T> Return(T value)
{
return new LazyList<T>(new[] { value });
}
public IEnumerable<T> AsEnumerable()
{
return _enumerable;
}
}
class Program
{
static LazyList<int> Choices(params int[] items)
{
return new LazyList<int>(items);
}
static LazyList<(int x, int y, int z)> Backtrack()
{
return
from x in Choices(1, 2, 3, 4, 5)
from y in Choices(1, 2, 3, 4, 5)
from z in Choices(1, 2, 3, 4, 5)
where x + y + z == 7
select (x, y, z);
}
static void Main()
{
foreach (var result in Backtrack().AsEnumerable())
{
Console.WriteLine($"{result.x}, {result.y}, {result.z}");
}
}
}