So, if you want to write out a line to the console in F#, you do the following:
System.Console.WriteLine "foo"
Originally I thought the following was pretty much identical, just more verbose, but actually it gives the error "A unique overload for method 'WriteLine' could not be determined based on type information prior to this program point":
(fun line -> System.Console.WriteLine line) "foo"
It seems the second version is confused by the presence of overloaded WriteLine methods that take a string as well as other arguments. Is my assumption along the right lines?
Not exactly. In the first case, the function call knows that it's being applied to a string literal, so it can do overload resolution to find the string overload.
In the second case, line is an unsolved type variable to type inference at the point of the call to the overloaded WriteLine method, so it doesn't know which overload to pick, and it hasn't seen the string argument yet, as type inference is left-to-right.
Change it to
"foo" |> (fun line -> System.Console.WriteLine line)
and it will work, because the type inference variable for line will get unified with string from "foo" coming in, before it needs to determine the WriteLine call.
So they key is left-to-right type inference; in the absence of a solution to a type variable, it may not be possible to pick an overload yet.
Related
In Python, I could see the variable's type by typing:
>>> i = 123
>>> type(i)
<type 'int'>
Is there a way to do this in F#?
F# is a .NET language, and in .NET all types are descendants of System.Object, which has a GetType method:
let i = 123
let t = i.GetType()
Having said that, I must strongly urge you not to rely on runtime type information, except for debugging or similar purposes. Doing so will make your program way less maintainable and will come back to bite you in the long run.
In Python you can get away with this, because Python is dynamically typed anyway, so one more check deferred to runtime doesn't really make a difference. But F# is statically typed, and by deferring types to runtime you throw away any support the compiler can provide.
If you're wanting to do this in F# Interactive, you just need to evaluate the variable by typing its name (followed by ;; as with any other expression at the F# Interactive prompt). I.e., if you've already executed let num = 123, then you just type num;; at the F# Interactive prompt and you'll see the following printed out:
val it : int = 123
The word val means that F# Interactive is describing a value. The name it is a special name in F# Interactive, assigned to the last value that was evaluated. Then comes a colon, the value's type (in this case, int), then an equals sign, and then the value is printed out.
So all you have to do to see the value and type of a variable in F# Interactive is to just type that variable followed by ;;. Simple.
I'm learning F#, when I type any code in Visual Studio and run them on F# Interactive it shows me things like
val foo : x:'a -> 'a
I imagine this mean that foo is a function that receive a paramater x of a type, and returns a value of same x's type.
But What does that ' mean? Many functions show such thing on intellisense too.
The single quote mark (') means that the type of that parameter is generic. It can be inferred, like the example you gave, or it can be explicitly applied.
See here under Implicitly Generic Constructs for more information.
'a represents a type variable, in other words a type that is not determined yet (and doesn't have to be determined yet).
Note that this is different than a', which is a regular variable whose name is two characters: a and '. Contrary to other languages like C#, the single quote is a permitted character in F# variable names, except as the first character in the name to disambiguate from type variables above.
Type inference in F# doesn't seem to work very well with parameters that are supposed to take values of a class type.
Is there a way to avoid explicit type annotation on such parameters?
It looks like a problem because when there are some 5 of such parameters each of which requires its pair of parentheses and a colon and the name of a type it looks much messier than the same declaration in C# which is known for being more syntactically noisy.
So that instead of
let writeXmlAttribute (writer: XmlWriter) name value = ()
I wish I could write something like
let writeXmlAttribute writer name value = () // <-- a problem when in comes to writer.WriteStartAttribute name
Is there a way I can get away with it?
UPDATE:
There is no such problem with records, only on classes.
If your primary reason for wanting to avoid this is a cleaner signature, you could move the explicit typing into the function with an upcast (which will infer the parameter type due to it being a compile-time determination). You're not avoiding it, however, you're just moving it.
let writeXmlAttribute writer name value =
(writer :> XmlWriter).WriteStartAttribute(name, value)
F# has difficulty with the kind of inference you're asking for in relation to members (including members on records), so you will have to do at least a minimal amount of explicit typing in any case.
I'm learning F#, when I type any code in Visual Studio and run them on F# Interactive it shows me things like
val foo : x:'a -> 'a
I imagine this mean that foo is a function that receive a paramater x of a type, and returns a value of same x's type.
But What does that ' mean? Many functions show such thing on intellisense too.
The single quote mark (') means that the type of that parameter is generic. It can be inferred, like the example you gave, or it can be explicitly applied.
See here under Implicitly Generic Constructs for more information.
'a represents a type variable, in other words a type that is not determined yet (and doesn't have to be determined yet).
Note that this is different than a', which is a regular variable whose name is two characters: a and '. Contrary to other languages like C#, the single quote is a permitted character in F# variable names, except as the first character in the name to disambiguate from type variables above.
Here's something I've seen in erlang code a few times, but it's a tough thing to google and I can only find this example (the first code block in link below):
http://www.process-one.net/en/wiki/ejabberd_HTTP_request_handlers/
In the "head" of function definition of process/2
process(_LocalPath = ["world"], _Request) ->
there is a pattern match on first parameter / argument;
Does this act similarly like a guard, so the following clause will be executed only if the first argument passed to process/2 is string "world", or is "world" some kind of a default argument? Or i completely misunderstood/ mis-guessed?
Yes, this is a pattern match. The clause will be executed if the first argument is a list with a single element, the element being the string "world".
You are correct: _LocalPath = ["world"] acts as a pattern "guard". If the first parameter to the function "process" isn't equal to ["world"], then the emulator proceeds to find a match down.
One thing to note: _LocalPath serves as "decorator" to enhance readability since the identifier starts with an underscore.
The = in a pattern is used for an alias, it basically allows you to have your cake and eat it. It both does a normal pattern match and binds a variable to the whole matched data. It is practical if you need the whole data as it saves you having to reconstruct it. You can use it anywhere in a pattern. It has nothing to do with guards.
Starting a variable with a _ as in _LocalPath is too tell the compiler not to complain if this variable is not used. Normally the compiler whines a bit if you bind variables and don't use them. Apart from this there is nothing special about variables whose names start with _, you can use them as you would any variable.
The only really special variable is _, the anonymous variable. It always matches and is never bound so you can use it as an anonymous place holder. Which is why it exists in the first place.
I personally very rarely use variables starting with _ and prefer to use just _. I also feel that cluttering up patterns with unnecessary things is a Bad Thing so I wouldn't use aliases for documentation like that. I would write:
%% process(LocalPath, Request) -> ... .
process(["world"], _) ->
or perhaps a type declaration if you prefer. Keeps the code shorter and more legible, I think.