References don't work?
Options
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?
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:
You need to fix two things. First, you need to cast the list (
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[1..10]
) to anIEnumerable
like this:let x = [1 .. 10] :> IEnumerable
. BecauseIEnumerable
is a non-generic enumerator interface, theCurrent
property returns an object that you need to cast back to an integer (i.e.let num = enumerator.Current :?> int
) because that's whatprintfn "%i"
expects. Here is the fixed code:open System
And here it is running in another F# Interactive session:
open System.Collections
let x = [1 .. 10] :> IEnumerable
let enumerator = x.GetEnumerator()
while enumerator.MoveNext() do
let num = enumerator.Current :?> int
printfn "%i" numMicrosoft (R) F# Interactive version 14.0.23413.0
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:
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 = ()open System
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
open System.Collections
let x = [1 .. 10] :> IEnumerable
let enumerator = x.GetEnumerator()
while enumerator.MoveNext() do
let num = enumerator.Current :?> int
printfn "%i" numSystem
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.