gre*_*gyb 1 f# types f#-interactive
我正在研究这个F#wikibook,我对链接页面的函数组合部分中看到的内容感到困惑.
我能想出的最简单的例子如下:
// int -> int
let f x = x + x
// float -> float
let g x = x + 1.0
Run Code Online (Sandbox Code Playgroud)
这可以.我很容易理解这些函数的类型,我可以在fsi中运行它们并确认它们采用并返回我在上面提到的类型的值.
如果我添加以下行,那么我看到变化我不太确定我理解.
// equivalent to f (g x)
let fog = f << g
Run Code Online (Sandbox Code Playgroud)
我理解这一点的方式,它应该不起作用,因为f期望一个int,但g返回一个浮点数.
如果我在fsi中定义这个组合,我会得到预期的类型错误.如果我将所有这些放在.fsx文件中并将整个内容发送到fsi,则f的签名将变为float - > float.
我对以下内容感到困惑:
我尝试过搜索,但目前我还不太了解这些问题的答案.如果你能帮我指出解决这些问题的部分,我会很乐意接受RTFM.
混淆来自这样一个事实,即虽然(+)运算符是通用的,但它有一个默认类型,这int取决于你正在编译的代码的其余部分,它将应用或不应用默认类型.
这意味着如果您只给出类型推断:
let f x = x + x
Run Code Online (Sandbox Code Playgroud)
它将被推断为int但它可能是支持(+)运算符的任何其他数字类型,但由于您没有提供更多信息,因此它使用默认值.
请注意,F#必须为此函数选择一种类型才能在.NET类型系统中进行编码,除非您定义它inline,否则它将保持通用.
let inline f x = x + x
// val inline f : x: ^a -> ^b when ^a : (static member ( + ) : ^a * ^a -> ^b)
Run Code Online (Sandbox Code Playgroud)
现在,如果您使用该函数编译其他代码,那么使用该函数f,类型推断可以分析类型并获得更准确的候选.
这是一个更简单的示例,打开一个新脚本并粘贴此代码:
let f x = x + x
let v = f 1.
Run Code Online (Sandbox Code Playgroud)
现在通过在每一行按CTRL+ 来逐行执行它',它将推断int并在第二行失败.
但是现在选择整个脚本并按ALT+ ENTER,它将被编译f并将被推断,float因为它能够使用以下行的信息使用f.