我有一个简单的函数调用需要两个元组。在类型上获取编译器错误:
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 )
错误2“float”类型与“int16”
类型不匹配不确定哪里出错了。有人可以帮忙吗?
谢谢!
答案 0 :(得分:6)
Math.Sqrt期望float的参数,但你传递int16。 F#不执行此类隐式转换
let side (x1,y1) (x2,y2) : float =
(x2 - x1)*(x2 - x1) + (y2 - y1)*(y2 - y1)
|> float
|> Math.Sqrt
或者你可以从一开始就传递花车:
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 )
答案 1 :(得分:6)
正如其他人已经指出的那样,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
这只能以floats
作为参数调用,因此您需要像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
我们只需要一个类型的注释(然后编译器会发现y1
,x2
,...也必须是int16
类型,因为我们正在增加/添加它们,只允许两个相同类型的值)。所以,现在你可以写:
side ( 2s, 3s ) ( 1s, 2s )
请注意,desco的版本有点棘手 - 它添加了转换(使用float
)函数,但它没有类型注释来指定参数的类型 - 在这种情况下,编译器将选择默认类型,即int
,因此如果您使用他的功能,则必须使用side (2,3) (1,2)
来调用它。
答案 2 :(得分:3)
您的函数的签名是float * float -> float * float -> float
,但您传递的是int16
值(这就是s
后缀的含义)。
将其编译的一种方法是执行此操作:
let a = side ( 2.0, 3.0 ) ( 1.0, 2.0 )