新手f#问题

Zhe*_*Lee 3 f# types tuples

我有一个简单的函数调用需要两个元组.在类型上获取编译器错误:

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'类型不匹配

不知道哪里出错了.有人可以帮忙吗?

谢谢!

des*_*sco 6

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)


Tom*_*cek 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
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).