Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Infinite Enumerables in C# #927

Open
WorldMaker opened this issue Nov 16, 2023 · 3 comments
Open

Infinite Enumerables in C# #927

WorldMaker opened this issue Nov 16, 2023 · 3 comments

Comments

@WorldMaker
Copy link

Regarding: https://blog.ploeh.dk/2023/11/14/cc-golf/

(Sorry, the comment formatting seemed a bit much for me to figure out just for this quick note.)

If there's a general API in .NET that corresponds to the F#-specific Seq.initInfinite I haven't found it

In System.Interactive (Ix.NET) there is an extension operator Enumerable.Repeat(value) that (truly 1) infinitely repeats a single value (without using System.Interactive there is a Repeat that requires a count).

Footnotes

  1. The source code shows it is exactly the simple generator you would think: https://github.com/dotnet/reactive/blob/main/Ix.NET/Source/System.Interactive/System/Linq/Operators/Repeat.cs

@ploeh
Copy link
Owner

ploeh commented Nov 17, 2023

How would you use that to enumerate a range?

@WorldMaker
Copy link
Author

WorldMaker commented Nov 18, 2023

Ah, the fun of dot-free styles and missing arguments were used.

If you wanted to do it a fun way, with Ix.NET you could always do:

var initInfinite = Enumerable.Repeat(1).Scan((acc, cur) => acc + cur, -1);

Though I don't think that's going to gain you much over Enumerable.Range(0, int.MaxValue) at that point, which is the effective limit anyway (unless you are trying for intentional overflow and want to throw in an unchecked { } in that Scan).

@ploeh
Copy link
Owner

ploeh commented Nov 18, 2023

I thad to modify that expression before I could make it work:

var initInfinite = EnumerableEx.Repeat(1).Scan(-1, (acc, cur) => acc + cur);

If one wants to take on a dependency on Ix, though, one could also use Generate:

var initInfinite = EnumerableEx.Generate(0, _ => true, x => x + 1, x => x);

It's approximately the same number of characters, though.

But nothing prevents one from just writing the generator oneself:

public static class EnumerablePloeh
{
    public static IEnumerable<T> Iterate<T>(T seed, Func<T, T> func)
    {
        var current = seed;
        while (true)
        {
            yield return current;
            current = func(current);
        }
    }
}

which can be used like this:

var initInfinite = EnumerablePloeh.Iterate(0, x => x + 1);

I've patterned that generator over Haskell's iterate function, rather than F#'s Seq.initInfinite, since the former is more general.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants