【问题标题】:F#. Expecting a type supporting the operator '-' but given a function typeF#。期望一个支持运算符“-”但给定函数类型的类型
【发布时间】:2019-09-21 00:08:22
【问题描述】:

我是 F# 新手,在这个代码片段中有一些编译问题:

let rec mywhile p f s =
    if p s then s
    else
       let s1 = f s
       mywhile p f s1

let eps = 0.001

let dichotomy f a b = 
    let out (a, b) = a
    let c a b = (a + b) / 2.
    out (mywhile (fun (a, b) -> a - b < eps)
        (fun (a, b) -> if f c * f a < 0 then (a, c) else (c, b))
        (a, b))

特别是这里:a - b &lt; eps, then (a, c)

期望一个支持运算符'-'的类型,但给定了一个函数类型。您可能缺少函数的参数。

【问题讨论】:

  • 当类型推断发生意想不到的事情时,它有助于注释那些你知道其类型的值(即使是暂时的)。在这种情况下,问题在于ab被推断为'a -&gt; 'b -&gt; float,这实际上是一个函数类型,不支持-运算符。当您将传递给mywhile 的第一个lambda 更改为(fun (a: float, b: float) -&gt; a - b &lt; eps) 时,下一行会显示更多错误,表明abc 的类型不兼容,这表明f 可能不兼容推断为您期望的类型,并且您可能希望使用注释来修复其类型。

标签: if-statement f#


【解决方案1】:

既然c被定义为c : float -&gt; float -&gt; float,而你写的是f c,那它一定意味着f : (float -&gt; float -&gt; float) -&gt; 'x(对于一些我们还不知道的'x)。

既然你也写了f a,而且我们已经知道f的参数是float -&gt; float -&gt; float,那就意味着a : float -&gt; float -&gt; float

这又意味着你不能从a 中减去任何东西。这是一个函数,而不是一个数字。这是编译器告诉你的。

通常,当您遇到不了解您的类型在做什么的情况时,请继续添加一些类型注释。它们将为编译器提供锚点,类型推断无法跨越的墙,因此将包含类型不一致。

例如,如果您指定f的类型:

let dichotomy (f : float -> float) a b =
   ...

这会立即显示f c 的错误,指出c 应该是float,但实际上是一个函数。

如果我理解正确,您的意思是将f 应用于(c a b),而不是c 本身。然后,相应地,在元组 (a, c)(c, b) 中返回相同的值:

out (mywhile (fun (a, b) -> a - b < eps)
    (fun (a, b) -> 
      let d = c a b
      if f d * f a < 0. then (a, d) else (d, b)
    )
    (a, b))

(另外,你的零是int;我在float后面加了一个点)

【讨论】:

    猜你喜欢
    • 2022-01-07
    • 1970-01-01
    • 1970-01-01
    • 2016-01-24
    • 1970-01-01
    • 2016-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多