【问题标题】:Why isn't it possible to use the same function twice with differently typed arguments?为什么不能使用不同类型的参数两次使用相同的函数?
【发布时间】:2013-07-20 13:19:01
【问题描述】:

我今天玩了一点 F#,写道:

let sq x = x * x

let i = sq 3
let d = sq 3.0

如果我删除第三行或第四行,它会编译,但如果两者都存在,则不会。

我收到错误This expression should have type 'int', but has type 'float'

【问题讨论】:

    标签: f# inline type-inference


    【解决方案1】:

    类型推断使您的函数sq 具有类型int -> int,因为编译器第一次看到您使用该函数时,您将其传递给一个整数。所以它假设sq是一个接受整数的函数,并且根据函数的定义(x * x)它也返回一个整数。

    在 F# 中定义一个完全通用的算术函数有点复杂,但一种方法是创建函数 inline,如下所示:

    let inline sq x = x * x
    

    这样,您的函数的主体每次都会在调用站点内联,因此使用内联的sq 函数与每次使用时都替换它的主体相同。

    这种方法有它的缺点,我想你看看this question会很有趣。

    【讨论】:

    • 据我所知,所有答案都是正确的 (+1),不过我从你那里学到的最多。
    【解决方案2】:

    let-bound 函数不能被重载。在您的特定情况下,您可以使用inline,它在编译时内联函数体,因此可以选择* 的适当实现,例如

    let inline sq x = x * x
    

    【讨论】:

      【解决方案3】:

      其他答案是正确的,但它们遗漏了拼图的一个重要部分:在 F# 中没有隐式转换,例如整数和浮点数。这就是为什么您的第二次调用实际上是使用浮点参数调用不同的、不存在的重载的原因。

      【讨论】:

        【解决方案4】:

        函数let sq x = x * x默认的类型为int -> int

        如果将其放在let d = sq 3.0 的上下文中,F# 编译器会将其类型推断为float -> float

        无论如何,此函数只能有一个类型签名,int->intfloat->float

        【讨论】:

          【解决方案5】:

          这是绑定实现方式的限制。有两种选择。

          首先,在声明中添加内联。

          其次,在类中使用成员绑定并覆盖不同的类型。

          【讨论】:

            猜你喜欢
            • 2022-01-22
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-07-09
            • 2021-03-18
            • 2016-04-18
            相关资源
            最近更新 更多