using System; using System.Collections; using System.Collections.Generic; using System.Runtime.CompilerServices; // enumerator = { next: lazylist } // enumeratorElement = { // current: U; // next: lazylist; // } // state = AlreadyUnfoldedEnd // | AlreadyUnfolded of ImmutableEnumeratorElement // | NotUnfoldedYet of IEnumerator // lazylist = state ref namespace Immutable { // enumerator = { next: lazylist } public partial class ImmutableEnumerator : IImmutableEnumerator { // state = AlreadyUnfoldedEnd // | AlreadyUnfolded of ImmutableEnumeratorElement // | NotUnfoldedYet of IEnumerator private abstract class State { public abstract T Match( Func AlreadyUnfolded, Func AlreadyUnfoldedEnd, Func, Last, T> NotUnfoldedYet); public class AlreadyUnfolded : State { private readonly ImmutableEnumeratorElement value; public AlreadyUnfolded(ImmutableEnumeratorElement value) { this.value = value; } public override T Match( Func AlreadyUnfolded, Func AlreadyUnfoldedEnd, Func, Last, T> NotUnfoldedYet) => AlreadyUnfolded(value); } public class AlreadyUnfoldedEnd : State { public AlreadyUnfoldedEnd() {} public override T Match( Func AlreadyUnfolded, Func AlreadyUnfoldedEnd, Func, Last, T> NotUnfoldedYet) => AlreadyUnfoldedEnd(); } public class NotUnfoldedYet : State { private readonly IEnumerator enumerator; private readonly Last last; // readonly public NotUnfoldedYet(IEnumerator enumerator, Last last) { this.enumerator = enumerator; this.last = last; } public override T Match( Func AlreadyUnfolded, Func AlreadyUnfoldedEnd, Func, Last, T> NotUnfoldedYet) => NotUnfoldedYet(enumerator, last); } } } }