【问题标题】:I can't figure out this F# error message我无法弄清楚这个 F# 错误消息
【发布时间】:2017-03-31 08:08:57
【问题描述】:

F# 编译器生成的错误消息有时令人困惑。例如:

open Deedle
let inds = [1;   2;  6;  8; 11; 12]
let vals = [10; 20; 30; 40; 50; 60]
let siv = Series(inds, vals)
let fbminmax b (s: Series<float, float>) =
    if b then (Seq.min s.Values) else (Seq.max s.Values)
let sgi =
    siv
    |> Series.groupInto (fun i _ -> i % 2 = 0) fbminmax
printfn "%A" <| sgi
// error FS0001: Type mismatch. Expecting a
//    'bool -> Series<int,int> -> 'a'    
// but given a
//    'bool -> Series<int,int> -> float'    
// The type 'float' does not match the type 'int'

我知道有一个错误(代码可以正常工作,Series&lt;int,int&gt; 替换 Series&lt;float,float&gt; 定义中的 fbminmax)。我知道一个

'bool -&gt; Series&lt;int,int&gt; -&gt; 'a'

是预期的。但我不明白为什么编译器说它被赋予了一个

'bool -&gt; Series&lt;int,int&gt; -&gt; float'

当它被赋予fbminmax时,这是一个

'bool -&gt; Series&lt;float,float&gt; -&gt; float'

此外,如果编译器确实被赋予了

'bool -&gt; Series&lt;int,int&gt; -&gt; float'

正如它声称的那样,float 扮演'a 的角色应该没问题。

有人可以提供一些关于发生了什么的见解吗?

【问题讨论】:

  • 我认为参数 i 是一个 int,也许因为 groupInto 它应该是一个浮点数。很难说,因为我无法编译。
  • 关于 lambda 的参数 i 的好点,但我认为编译器指的是 fbminmax 而不是 lambda,即 int -&gt; 'b -&gt; bool
  • 我不明白为什么它错误识别了fbminmax的参数类型,但我想知道Deedle的Series类型是否内置了从intfloat的任何隐式转换运算符?虽然 F# 不允许您将 ints 传递给期望 floats 的函数,但它构建在 CLI 之上,并且 CLI 层可能会发生一些事情(我不完全理解)这导致错误消息中报告的类型不太正确。我想知道如果您将代码反编译为 IL 指令,您会看到什么?
  • @rmunn - 关于 IL 指令的好建议。我会尝试,但需要几天时间,因为周末我将无法访问我的系统。

标签: compiler-errors f#


【解决方案1】:

编译器错误消息确实有些神秘。解决方案:让它通用:-)

let fbminmax b (s: Series<'T, 'T>) =
    if b then (Seq.min s.Values) else (Seq.max s.Values)

最终的问题是您指定了fbminmax b (s: Series&lt;float, float&gt;),但将一系列ints 输入其中。

【讨论】:

  • 我知道我喂的是&lt;float,float&gt;而不是&lt;int,int&gt;。在我的问题中,我写了the code works fine with Series&lt;int,int&gt;。将其设为通用可以解决问题,编写 Series&lt;int,int&gt; 也可以解决问题。我的问题是错误消息没有意义,而不是有错误,我是为了说明问题而特意引入的。
  • 是的,我知道。如果您更改订单,它也会抱怨siv。我最好的猜测是,进入 groupInto 的管道需要 int,然后 fbminmax 需要 float,然后这两件事就会混淆。无论解释如何,该消息都没有真正的帮助。但这也不值得浪费太多时间。解决这些问题的一般方法是开始注释,然后删除注释。此外,通常最好让函数尽可能通用。
【解决方案2】:

只是猜测,但是当您尝试使 int 浮动时,编译器会说什么?

来自:

let inds = [1;   2;  6;  8; 11; 12]
let vals = [10; 20; 30; 40; 50; 60]

到:

let inds = [1.0;   2.0;  6.0;  8.0; 11.0; 12.0]
let vals = [10.0; 20.0; 30.0; 40.0; 50.0; 60.0]

【讨论】:

  • 在这种情况下,代码可以正常工作。我还必须将fbminmax 定义中的常量从int 更改为float
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多