F# 为什么不是';对于不同类型的参数,不可能使用同一个函数两次吗?
我今天和F#玩了一会儿,写了这样一段话:F# 为什么不是';对于不同类型的参数,不可能使用同一个函数两次吗?,f#,inline,type-inference,F#,Inline,Type Inference,我今天和F#玩了一会儿,写了这样一段话: let sq x = x * x let i = sq 3 let d = sq 3.0 如果删除第三行或第四行,它将编译,但如果两行都存在,则不会编译 我得到一个错误这个表达式应该有类型“int”,但是有类型“float”函数让默认的sq x=x*x有类型int->int 如果将其放在let d=sq 3.0的上下文中,F#编译器将推断其类型为float->float 无论如何,此函数只能有一个类型签名,要么是int->int,要么是float->
let sq x = x * x
let i = sq 3
let d = sq 3.0
如果删除第三行或第四行,它将编译,但如果两行都存在,则不会编译
我得到一个错误
这个表达式应该有类型“int”,但是有类型“float”
函数让默认的sq x=x*x
有类型int->int
如果将其放在let d=sq 3.0
的上下文中,F#编译器将推断其类型为float->float
无论如何,此函数只能有一个类型签名,要么是
int->int
,要么是float->float
,这是绑定实现方式的限制。有两种选择
首先,将内联添加到声明中
其次,在类中使用成员绑定并重写不同的类型。让绑定函数不能重载。在您的特定情况下,您可以使用
inline
,它在编译时内联函数体,因此可以选择*
的适当实现,例如
let inline sq x = x * x
类型推断的工作原理是,您的函数
sq
具有类型int->int
,因为编译器第一次看到您使用该函数时,会传递一个整数。因此它假设sq
是一个接受整数的函数,并且根据函数(x*x
)的定义,它还返回一个整数
在F#中定义一个完全通用的算术函数有点复杂,但一种方法是将函数内联,如下所示:
let inline sq x = x * x
这样,每次调用站点都会内联函数体,因此使用内联sq
函数与每次使用时替换函数体是一样的
这种方法有它的缺点,我想你会感兴趣地看到。其他答案是正确的,但它们忽略了拼图的一个重要部分:在F#中,例如int和float之间没有隐式转换。这就是为什么您的第二个调用实际上是使用float参数调用一个不同的、不存在的重载 就我所知,我从你那里学到的最多。