Home

References don't work?

I just started with LINQPad 5 and I am not very experienced (to say the least) with .NET. I have the following F# script that runs in Visual Studio:

open System
open System.Collections

let x = [1 .. 10]

let enumerator = x.GetEnumerator()

while enumerator.MoveNext() do
let num = enumerator.Current
printfn "%i" num

LINQPad complains about the first line, says Unmatched '('.

I tried to add the references using the F4 key. The two DLLs show in the Query Properties window that pops up. After removing the two open statements I still get an error, with the message:

The field constructor or member 'GetEnumerator' is not defined (using external F# compiler)

What am I doing wrong?

Comments

  • I'm surprised that it runs in VS. I tried your script in F# Interactive (fsi) and I got, not surprisingly, an error:

    Microsoft (R) F# Interactive version 14.0.23413.0
    Copyright (c) Microsoft Corporation. All Rights Reserved.

    For help type #help;;

    > open System
    - open System.Collections
    -
    - let x = [1 .. 10]
    -
    - let enumerator = x.GetEnumerator()
    -
    - while enumerator.MoveNext() do
    - let num = enumerator.Current
    - printfn "%i" num
    - ;;

    let enumerator = x.GetEnumerator()
    -------------------^^^^^^^^^^^^^

    stdin(6,20): error FS0039: The field, constructor or member 'GetEnumerator' is not defined
    You need to fix two things. First, you need to cast the list ([1..10]) to an IEnumerable like this: let x = [1 .. 10] :> IEnumerable. Because IEnumerable is a non-generic enumerator interface, the Current property returns an object that you need to cast back to an integer (i.e. let num = enumerator.Current :?> int) because that's what printfn "%i" expects. Here is the fixed code:
    open System
    open System.Collections

    let x = [1 .. 10] :> IEnumerable

    let enumerator = x.GetEnumerator()

    while enumerator.MoveNext() do
    let num = enumerator.Current :?> int
    printfn "%i" num
    And here it is running in another F# Interactive session:
    Microsoft (R) F# Interactive version 14.0.23413.0
    Copyright (c) Microsoft Corporation. All Rights Reserved.

    For help type #help;;

    > open System
    - open System.Collections
    -
    - let x = [1 .. 10] :> IEnumerable
    -
    - let enumerator = x.GetEnumerator()
    -
    - while enumerator.MoveNext() do
    - let num = enumerator.Current :?> int
    - printfn "%i" num
    - ;;
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10

    val x : System.Collections.IEnumerable = [1; 2; 3; 4; 5; 6; 7; 8; 9; 10]
    val enumerator : System.Collections.IEnumerator
    val it : unit = ()
    Back in LINQPad, make sure the query language is set to F# Program and then you should be able to just run the same code:
    open System
    open System.Collections

    let x = [1 .. 10] :> IEnumerable

    let enumerator = x.GetEnumerator()

    while enumerator.MoveNext() do
    let num = enumerator.Current :?> int
    printfn "%i" num
    The `open` import declarations are harmless and can be omitted in LINQPad because I think it does that for you for quite a few of the commonly used System namespaces.
  • I am sorry, you are right. The original code does not run in fsi. Somehow I got confused. The code with the two fixes you kindly provided works in LINQPad (if the Default Query Language is set to F# Program, but not if it is set to F# Expression). Indeed it runs in LINQPad with or without the two open statements, as you pointed out.

    The fixed code runs within a project or in fsi, but only if the two open statements are included.

    Many thanks for your help. I thought a list would be automatically enumerable, and in hindsight it is clear that casting Current to int is necessary for the print statement to work.

    I tried static casting (enumerator.Current :> int, "?" omitted) and it did not work. Being a beginner (three days with F#) I still do not know why.
Sign In or Register to comment.