Why can't Console.WriteLine determine my type? in F# -
here's code:
open system let places = [ ("grandchester", 552); ("cambridge", 117900); ("prague", 1188126); ] let statusbypopulation = function | n when n > 1000000 -> "city" | n when n > 50000 -> "town" | _ -> "village" system.console.writeline ( places |> list.map (fun (_, population) -> statusbypopulation population)) let print x = console.writeline (list.map (fun (_, population) -> statusbypopulation population) x) // i'm trying let (x:(string * int) list) = list.map (fun (_, population) -> statusbypopulation population) x; // checking kinf of type returns let print: (string * int) list -> unit = console.writeline << list.map (fun (_, population) -> statusbypopulation population) // i'm not allowed system.console.readkey () |> ignore
i wanted familiar way function composition operator worked, reason f# can't find best possible overload function...
in example explicitly state parameter, sets type val print : x:('a * int) list -> unit
, explicitly set type in function composition operator <<
hoping i'd correct result... didn't...
i made function something
explicitly declared type parameter, see it'd return... returns this: val : x:(string * int) list -> string list
so returns type... list of strings, know console.writeline capable of printing... why tell me can't determine overload?
the type inference in f# works left right - means compiler uses information available earlier in program determine types of expressions later in program (this slight simplification, general idea).
so in code, when write:
console.writeline << list.map (fun (_, population) -> statusbypopulation population)
.. compiler not propagate information type of function input through list.map
call writeline
call. explains why forward chaining , composition more useful in f#. following works:
list.map (fun (_, population) -> statusbypopulation population) >> console.writeline
to original code working, provide minimal amount of information needed determine right writeline
overload 1 taking object
. if tell compiler needs take list of something, can choose right overload:
(console.writeline:list<_> -> unit) << list.map (fun (_, population) -> statusbypopulation population)
Comments
Post a Comment