F#函数组成更改基函数类型

时间:2016-12-31 16:50:12

标签: types f# f#-interactive

我正在处理this F# wikibook,我对链接页面的功能组合部分中看到的内容感到困惑。

我能提出的最简单的例子如下:

// int -> int
let f x = x + x
// float -> float
let g x = x + 1.0

这很好。我很容易理解这些函数的类型,我可以在fsi中运行它们并确认它们采用并返回我上面提到的类型的值。

如果我添加以下行,那么我看到了改变,我不太清楚我理解。

// equivalent to f (g x)
let fog = f << g

我理解这一点的方式,它应该不起作用,因为f期望一个int,但是g返回一个浮点数。

如果我在fsi中定义这个组合,我会得到预期的类型错误。如果我将所有这些放在.fsx文件中并将整个内容发送到fsi,则f的签名将变为float - &gt;浮。

我对以下内容感到困惑:

  • 类型推断的范围发生了吗?
  • 在文件和fsi中定义它们之间的区别是什么?

我尝试过搜索,但目前我还不太了解这些问题的答案。如果你能帮我指出解决这些问题的部分,我会很乐意接受RTFM。

1 个答案:

答案 0 :(得分:6)

虽然(+)运算符是通用的,但它具有int的默认类型,因此根据您编译的其余代码,它将适用或不适用默认类型。

这意味着如果您仅提供类型推断:

let f x = x + x

它将被推断为int但它可能是支持(+)运算符的任何其他数字类型,但由于您没有提供更多信息,因此它使用默认值。

请注意,F#必须为此函数选择一种类型才能在.NET类型系统中进行编码,除非您定义它inline,否则它将保持通用。

let inline f x = x + x

// val inline f :  x: ^a ->  ^b when  ^a : (static member ( + ) :  ^a *  ^a ->  ^b)

现在,如果您使用函数f编译其他代码,那么类型推断可以分析类型并获得更准确的候选。

这是一个更简单的示例,打开一个新脚本并粘贴此代码:

let f x = x + x
let v = f 1.

现在在每一行按CTRL + '逐行执行,它会推断int并在第二行失败。

但现在选择整个脚本并按ALT + ENTER,它将进行编译,f将与float一起推断,因为它能够使用以下行使用f