F# 函数组合更改基函数类型
F# function composition changes base function types
我正在研究 this F# wikibook,我对在链接页面的功能组合部分看到的内容感到困惑。
我能想到的最简单的例子如下:
// int -> int
let f x = x + x
// float -> float
let g x = x + 1.0
这很好。我很容易理解这些函数的类型,我可以在 fsi 中 运行 它们并确认它们采用我上面提到的类型的 return 值。
如果我添加以下行,然后我看到了我不太确定我理解的变化。
// equivalent to f (g x)
let fog = f << g
按照我的理解,它不应该起作用,因为 f 需要一个 int,但是 g return 是一个 float。
如果我在 fsi 中定义这个组合,我会得到预期的类型错误。如果我将所有这些放在一个 .fsx 文件中并将整个文件发送给 fsi,则 f 的签名变为 float -> float.
我对以下内容感到困惑:
- 发生类型推断的范围?
- 在文件中和在 fsi 中定义这些有什么不同?
我已尝试搜索,但目前我还不够了解,无法有效地找到这些问题的答案。如果你能帮我指出解决这些问题的部分,我会很高兴 RTFM。
混淆来自这样一个事实,即虽然 (+)
运算符是通用的,但它有一个默认类型 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
并在第二行失败。
但现在 select 整个脚本并按 ALT
+ ENTER
,它将编译并且 f
将被推断为 float
因为它是能够使用以下使用 f
.
的行的信息
我正在研究 this F# wikibook,我对在链接页面的功能组合部分看到的内容感到困惑。
我能想到的最简单的例子如下:
// int -> int
let f x = x + x
// float -> float
let g x = x + 1.0
这很好。我很容易理解这些函数的类型,我可以在 fsi 中 运行 它们并确认它们采用我上面提到的类型的 return 值。
如果我添加以下行,然后我看到了我不太确定我理解的变化。
// equivalent to f (g x)
let fog = f << g
按照我的理解,它不应该起作用,因为 f 需要一个 int,但是 g return 是一个 float。
如果我在 fsi 中定义这个组合,我会得到预期的类型错误。如果我将所有这些放在一个 .fsx 文件中并将整个文件发送给 fsi,则 f 的签名变为 float -> float.
我对以下内容感到困惑:
- 发生类型推断的范围?
- 在文件中和在 fsi 中定义这些有什么不同?
我已尝试搜索,但目前我还不够了解,无法有效地找到这些问题的答案。如果你能帮我指出解决这些问题的部分,我会很高兴 RTFM。
混淆来自这样一个事实,即虽然 (+)
运算符是通用的,但它有一个默认类型 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
并在第二行失败。
但现在 select 整个脚本并按 ALT
+ ENTER
,它将编译并且 f
将被推断为 float
因为它是能够使用以下使用 f
.