F#vs Scala - 为什么我需要告诉F#什么类型的东西?

Noa*_*oam 1 f# functional-programming scala type-inference

我开始在F#(和Scala)冒险.FunProg人们喜欢谈论的主要好处之一是类型推断.在Scala中我可以这样写:

  val x = List(1,2,3)
  x map ((x) => x+1)
Run Code Online (Sandbox Code Playgroud)

并且编译器知道x是一个列表,因此知道使用map函数的map变量.更进一步,我可以在任何具有map运算符的对象上使用第二个,不管它是什么(list,array,Seq,...)

另一方面,从我见过的关于F#的所有样本中,您必须执行以下操作:

let x = [1;2;3];;
x |> List.map(fun f -> f+1);;
Run Code Online (Sandbox Code Playgroud)

所以我需要知道并定义什么类型x是明确使用的List.map.这对我来说没什么意义,并且否定了整个"不要担心类型"的论点.

我错过了关于F#的一些事情吗?有一个更好的方法吗?

Gus*_*Gus 6

这不是类型推理限制.问题是F#core lib不提供具有重载机制的泛型函数.实际上有一些,主要是针对通用数字和其他东西,但只是少数.

如果您想以该样式编写F#代码,可以查看F#+.使用该库,编写完全有效:

let x = [1;2;3];;
x |> map (fun f -> f+1);;

// val it : int list = [2; 3; 4]
Run Code Online (Sandbox Code Playgroud)

它会为你推断出类型.

let y = Some 2
x |> map (fun f -> f+1);;

// val it : int option = Some 3
Run Code Online (Sandbox Code Playgroud)

它也适用于任何具有Map静态方法的类型.

所以,正如你可以看到F#类型的推断,它也足够聪明.这只是因为函数是按模块组织的.

除此之外,有一个建议允许你写下这样的东西:

x |> _.map;;
Run Code Online (Sandbox Code Playgroud)

要么

x |> (.map);;
Run Code Online (Sandbox Code Playgroud)

但这只适用于实例成员,所以因为List.map它现在不会起作用.