为什么F#在这个函数中推断int?

时间:2017-04-21 08:41:06

标签: f# type-inference

在F#中,我可以将字符串与+运算符组合,如下所示:

let myString = "one" + "two"

但是当我创建一个接受两个参数并应用相同运算符的函数时,我把它放在一个在其使用之前声明的模块中,F#将这些类型推断为整数:

module StringFunctions = 

let add str1 str2 = 
    str1 + str2

调用下面的代码给出了构建错误,“表达式应该有'int'类型,但这里有'string'类型”:

let str3 = StringFunctions.add "three" "four"

为什么F#将其推断为int?我假设它不能是通用方法,因为并非所有类型都会实现+运算符,但为什么它假设为int?

1 个答案:

答案 0 :(得分:5)

短版本是"因为那是F#的设计方式"。

较长的版本是,如果某个功能的类型不具有通用性(并且你能够纠正这个类型,那么因为并非所有类型都必须补充{{1操作员),然后F#必须选择一个真实的类型。 +运算符最常见的用例是添加整数,因此F#默认假设+是整数加法运算符,除非你另有说明。

否则你可以告诉它的另一种方法是输入一个类型注释:

+

请注意,您不必注释这两个参数:知道let add (str1 : string) str2 = str1 + str2 运算符的一侧是字符串就足以让F#推断另一侧也必须是字符串。< / p>

你可以做的另一件事是制作函数+,这将产生两件事:

  1. F#不会将其编译为函数调用,但实际上函数的代码插入到调用位置,并且
  2. 因此,如果需要,F#编译器将能够在不同的呼叫位置使用不同的 inline运营商。
  3. 也就是说,+将成为使用整数加法运算符的add 3 5,而3 + 5将成为add "foo" "bar",它使用{{1}的字符串加法重载}}

    此问题的原因在F# generics / function overloading syntaxUse of `inline` in F#等问题中更深入,所以我不会在这里进入。

相关问题