F# - 乘以float乘以int

Leo*_*ens 7 f# functional-programming

可能是一个愚蠢的问题,但我刚开始使用F#而且我遇到了一些问题.

说我有这样的功能:

let multiplyByTwo x = x * 2
Run Code Online (Sandbox Code Playgroud)

当我这样称呼时:

let result = multiplyByTwo 5
Run Code Online (Sandbox Code Playgroud)

一切都好,结果是10.

当我这样称呼时:

let result = multiplyByTwo 2.5
Run Code Online (Sandbox Code Playgroud)

我希望得到5或5.0.但实际结果如下:

let result = multiplyByTwo 2.5 ;;
--------------------------------- ^^^

stdin(4,28):错误FS0001:此表达式应该具有类型

int     
Run Code Online (Sandbox Code Playgroud)

但这里有类型

float
Run Code Online (Sandbox Code Playgroud)

因为我希望这个函数有点通用(即接受浮点数和整数),我不喜欢这个.我的问题当然是:如何解决这个问题?

Tom*_*cek 14

当您在F#中编写数字文字(例如23.14)时,编译器会将其视为特定类型的值,因此使用数字文字的代码不会是多态的.您可以将输入转换为单一类型并使用该类型(如floatdesco的答案)或使用F#的更高级功能...

某些数字操作可以以多态方式编写,如果您将代码标记为inline(这样,编译器可以表示其他约束并静态解析它们),并且如果您只使用多态基元(具有其他静态约束).

标准运算符在inline函数中是多态的,F#库提供了一种获取表示1和0(但不是2)的多态值的方法,但这足以编写您想要的函数:

let inline twoTimes n = 
  let one = LanguagePrimitives.GenericOne
  n * (one + one)

twoTimes 2
twoTimes 2.0
Run Code Online (Sandbox Code Playgroud)

如果你想使这个更好,你可以定义一个数字文字(参见Daniel对早期StackOverflow问题的回答)然后你可以实际写:

let inline twoTimes n = n * 2G
Run Code Online (Sandbox Code Playgroud)

特殊的数字文字2G被转换为对函数的调用,该函数NumericLiteralG使用我上面使用的技术对指定数量的通用1值求和(因此对于大数字而言效率不高!)有关更多信息,请参阅我最近的文章就在F#编写通用的数字代码.


des*_*sco 12

let inline mulBy2 x = (float x) * 2.0

let a = mulBy2 3 // 6.0 : float
let b = mulBy2 2.5 // 5.0 : float
let c = mulBy2 "4" // 8.0 : float
Run Code Online (Sandbox Code Playgroud)