【问题标题】:Why does F# infer int in this function?为什么 F# 在这个函数中推断 int?
【发布时间】:2017-04-21 08:41:06
【问题描述】:

在 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?

【问题讨论】:

标签: f# type-inference


【解决方案1】:

简短的版本是,“因为 F# 就是这样设计的”。

更长的版本是,如果一个函数的类型不能是泛型的(你是对的,因为并非所有类型都必须实现+ 运算符),那么 F# 必须选择一个真正的类型。 + 运算符最常见的用例是整数相加,因此 F# 默认假设 + 是整数加法运算符,除非您另有说明。

你可以告诉它的一种方法是放入类型注释:

let add (str1 : string) str2 = str1 + str2

请注意,您不必同时注释两个参数:知道+ 运算符的一侧是字符串就足以让 F# 推断另一侧也必须是字符串。

您可以做的另一件事是创建函数inline,这将导致两件事:

  1. F# 不会将此编译为函数调用,但实际上会将函数的代码插入到调用位置,并且
  2. 因此,如果需要,F# 编译器将能够在不同的调用位置使用不同的 + 运算符。

也就是说,add 3 5 将变为使用整数加法运算符的3 + 5add "foo" "bar" 将变为使用+ 的字符串加法重载的"foo" + "bar"

这项工作的原因在F# generics / function overloading syntaxUse of `inline` in F#(以及其他)等问题中进行了更深入的探讨,因此我不会在这里深入探讨。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-01-11
    • 2022-11-28
    • 1970-01-01
    • 2017-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多