F#: Downcast seq to IEnumerator

f#, ienumerator, seq

Solution

A sequence expression creates an object that implements `IEnumerable<T>` and `IEnumerator<T>`

let s = seq { for i in 0 .. 4095 do yield i }
printfn "%b" (s :? IEnumerable<int>) // true
printfn "%b" (s :? IEnumerator<int>) // true

But `Seq.init` does not:

let s = Seq.init 4095 (fun i -> i)
printfn "%b" (s :? IEnumerable<int>) // true
printfn "%b" (s :? IEnumerator<int>) // false

You could refactor your code to use `IEnumerable<T>` instead of `IEnumerator` since both constructs produce an `IEnumerable<T>`.

Alternatively, if you really want an `IEnumerator`, you could simply call `GetEnumerator` to return an `Enumerator` from an `Enumerable`:

let s = (Seq.init 4095 (fun i -> i)).GetEnumerator()
printfn "%b" (s :? IEnumerable<int>) // false
printfn "%b" (s :? IEnumerator<int>) // true

Problem

Why is it that in F#, I can do this... ``` let s = seq { for i in 0 .. 4095 do yield i } :?> IEnumerator ``` ... but this throws a `System.InvalidCastException`? ``` let s = Seq.init 4095 (fun i -> i) :?> IEnumerator ```

Original source