【问题标题】:F# Types and Function signaturesF# 类型和函数签名
【发布时间】:2017-07-28 19:53:41
【问题描述】:

我是 F# 的新手,我正在尝试一些事情来理解这门语言。

我必须有两种几乎相同的类型(坐标和矢量)。由于这种类型推断无法正常工作,我很难为每个函数指定正确的类型。

它不知何故不明白这里是一个向量:

type Coordinate = {X:int; Y:int}
type Vector = {X:int; Y:int}

let calculateVector (origin:Coordinate) (destination:Coordinate) = { X=destination.X-origin.X; Y= destination.Y-origin.Y;}

当我想要一个坐标的返回类型时,我找不到如何为这个函数指定返回它:

let calculateNextCoordinate (coordinate:Coordinate) direction = 
   match direction with
   | "N" -> { X=coordinate.X; Y=coordinate.Y-1 }
   | "NE" -> { X=coordinate.X+1; Y=coordinate.Y-1 }
   | "E" -> { X=coordinate.X+1; Y=coordinate.Y }
   | "SE" -> { X=coordinate.X+1; Y=coordinate.Y+1 }
   | "S" -> { X=coordinate.X; Y=coordinate.Y+1 }
   | "SW" -> { X=coordinate.X-1; Y=coordinate.Y+1 }
   | "W" -> { X=coordinate.X-1; Y=coordinate.Y }
   | "NW" -> { X=coordinate.X-1; Y=coordinate.Y-1 }
   | _ -> coordinate

默认情况下我有这个错误:这个表达式应该有'Vector'但这里有类型'Coordinate'

我厌倦了在这个网站上查看函数签名,但无法解决我的问题:https://fsharpforfunandprofit.com/posts/function-signatures/

问题:

你如何解决这个错误?

是不是因为推理类型默认采用与属性匹配的最后一个声明类型(在我的示例中为 Vector)?

奖励:在 F# 中是否有更好的方法来处理这种情况?

提前致谢

【问题讨论】:

    标签: f# type-inference


    【解决方案1】:

    由于记录是使用其成员名称构建的:

    { X = 2; Y = 3}
    

    您在向量和坐标之间造成了命名冲突。在 F# 中,编译器总是在这种情况下解析为最新定义,因此,在您的示例中,编译器会将记录 { X = ..., Y = ...} 解释为 Vector。

    F# records on fsharpforfunandprofit.com 上有一篇很好的文章,解释了如何轻松处理这个问题,我建议你阅读这篇文章以获得很好的解释。

    但简而言之,您可以在记录实例的任一成员前面加上记录类型:

    { Coordinate.X = 2; Y = 3 }  // Creates a Coordinate
    { X = 2; Coordinate.Y = 3 }  // Creates a Coordinate
    

    { Vector.X = 2; Y = 3 } // creates a vector
    

    【讨论】:

    • 感谢我一直在寻找的东西,而且链接真的很好。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-24
    • 1970-01-01
    • 2017-06-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多