我有一个简单的函数调用需要两个元组.在类型上获取编译器错误:
module test
open System.IO
open System
let side (x1,y1) (x2,y2) : float =
Math.Sqrt((x2 - x1)*(x2 - x1) + (y2 - y1)*(y2 - y1))
let a = side ( 2s, 3s ) ( 1s, 2s )
Run Code Online (Sandbox Code Playgroud)
错误2类型'float'与'int16'类型不匹配
不知道哪里出错了.有人可以帮忙吗?
谢谢!
Math.Sqrt期望float的参数,但你传递int16.F#不执行此类隐式转换
let side (x1,y1) (x2,y2) : float =
(x2 - x1)*(x2 - x1) + (y2 - y1)*(y2 - y1)
|> float
|> Math.Sqrt
Run Code Online (Sandbox Code Playgroud)
或者你可以从一开始就传递花车:
let side (x1,y1) (x2,y2) : float = Math.Sqrt((x2 - x1)*(x2 - x1) + (y2 - y1)*(y2 - y1))
let a = side ( 2.0, 3.0 ) ( 1.0, 2.0 )
Run Code Online (Sandbox Code Playgroud)
正如其他人已经指出的那样,F#编译器不会自动在数字类型之间插入任何转换.这意味着如果你正在编写一个与浮点数一起工作的函数,你需要将它作为参数传递给浮点数.
示例中的函数可以使用各种类型,因为Math.Sqrt数字运算符会被重载.如果你在没有任何类型注释的情况下编写它,你将得到一个使用浮点数的函数(因为Math.Sqrt只适用于浮点数):
> let side (x1,y1) (x2,y2) =
Math.Sqrt((x2 - x1)*(x2 - x1) + (y2 - y1)*(y2 - y1));;
val side : float * float -> float * float -> float
Run Code Online (Sandbox Code Playgroud)
这只能用floatsas参数调用,所以你需要像Joel建议的那样调用它.如果要获取一个将其他类型的数字作为参数的函数,则需要添加类型注释和转换.我会这样写:
> let side (x1:int16,y1) (x2,y2) =
let n = (x2 - x1)*(x2 - x1) + (y2 - y1)*(y2 - y1)
Math.Sqrt(float(n));;
val side : int16 * int16 -> int16 * int16 -> float
Run Code Online (Sandbox Code Playgroud)
我们只需要一个类型的注释(然后编译器会发现y1,x2...也必须是类型int16,因为我们将它们相乘/相加,并且只允许两个相同类型的值).所以,现在你可以写:
side ( 2s, 3s ) ( 1s, 2s )
Run Code Online (Sandbox Code Playgroud)
需要注意的是版本由德斯科是有点棘手-它增加了转换(使用float)的功能,但它不具有类型批注指定参数的类型-在这种情况下,编译器会选择一个默认类型是int,所以如果你使用他的功能,你将不得不使用它side (2,3) (1,2).