[英]Why can't Console.WriteLine determine my type? in F#
这是我的代码:
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) // what I'm trying to do
let something (x:(string * int) list) =
List.map (fun (_, population) -> statusByPopulation population) x; // checking what kinf of type it returns
let print: (string * int) list -> unit =
Console.WriteLine << List.map (fun (_, population) -> statusByPopulation population) // what I'm not allowed to do
System.Console.ReadKey () |> ignore
我想熟悉函数组合运算符的工作方式,但由于某种原因,F#无法找到函数的最佳可能重载...
在我明确声明参数的示例中,它将类型设置为val print : x:('a * int) list -> unit
,所以我使用复合运算符<<
hoping I'在函数中显式设置类型d得到正确的结果......我没有......
然后我做了功能something
用显式声明的类型参数,只是为了看看它会返回......它返回: val something : x:(string * int) list -> string list
所以它肯定会返回一个类型...一个字符串列表,我知道Console.WriteLine能够打印...那么为什么它告诉我它无法确定过载?
F#中的类型推断从左到右工作 - 这意味着编译器使用程序中较早的可用信息来确定程序中稍后的表达式类型(这是一种轻微的简化,但这是一般的想法)。
所以在你的代码中,当你写:
Console.WriteLine << List.map (fun (_, population) -> statusByPopulation population)
..编译器不会通过List.map
调用将有关函数输入类型的信息传播回WriteLine
调用。 这也解释了为什么正向链接和组合通常在F#中更有用。 以下作品:
List.map (fun (_, population) -> statusByPopulation population) >> Console.WriteLine
要使原始代码正常工作,您可以提供一些最少量的信息,以确定正确的WriteLine
重载是获取object
的一个。 如果你告诉编译器需要列出某个东西,那么它可以选择正确的重载:
(Console.WriteLine:list<_> -> unit) << List.map (fun (_, population) ->
statusByPopulation population)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.