![]() |
Edit |
![]() |
|
![]() |
Recent Changes |
![]() |
Subscriptions |
![]() |
Lost and Found |
![]() |
Find References |
![]() |
Rename |
| Search |
![]() |
List all versions |
Check out the formatting tips on the right for help formatting and making links.
Use the template below:
Pasting code into FSC line by line can reveal differences in the treatment of type inference. This is due to differences in the scope of type inference, and in particular the ValueRestriction. The scope of type inference for fsi is the chunks that are separated by ";;" terminators. The scope for fsc is an entire file.
For example, the following code compiles and runs just fine with fsc.exe
open System
open System.IO
let realfun (f:> TextWriter) line =
f.WriteLine (line :> obj);;
let newfun = realfun Console.Out;;
let _ =
newfun "newfun, realfun.";;
However, if stepping through in the top-level, fsi reports error when defining the function - newfun. Below is the error message.
> let newfun = realfun Console.Out;;
toplevel(2,4): error: FS0030: Type inference has inferred the signature
val newfun : ('a -> unit)
for 'newfun', but the definition of 'newfun' involves some computation, i.e.
it is not defined as an immediate function. Either define 'newfun' as an
immediate, or add a type constraint to instantiate the type parameters.
This wouldn't matter except that languages like OCaml and F# cannot make all bindings as generic (polymorphic) as one might wish. This is called the "value restriction", and is covered in depth elsewhere, e.g. section 5.1.1 of http://www.cs.caltech.edu/courses/cs134/cs134b/book.pdf. This means that some type parameters can end up being unresolved unknowns, though by the end of a scope of type inference these must have been resolved.
The F# toplevel is a bit stricter than OCaml in this regard. In OCaml the toplevel is a single never-ending type inference scope, and the "newfun" binding one would have been assigned the type
val newfun : ('_a -> unit)
where a represents an unresolved type inference variable, rather than a true generic type parameter. The subsequent binding then enforces the constraint 'a = string. F# cannot play this trick, because it cannot execute code without concrete values for type variables, due to the fact that it translates to .NET IL before execution, which is a typed intermediary language.
We don't think there's much we can do about this in the short term.
This means you will either have to paste across a larger chunk of your file or add a type annotation.
Some previous release of fsi saw small inconsistencies between fsi and fsc in this release, e.g. "open" declarations must be followed by a ";;".
These no longer occur.
![]() |
| This site supports the new NoFollow anti-spam initiative. |
Recent Topics