f# - 如何在 f# 中为可区分联合定义运算符

标签 f# discriminated-union

我有代码可以在图元之间实现一些几何运算

type point = double * double
type shape =
    | Point of point
    | Line of point * point
    | Vector of point
    | Circle of point * double
    with
    member this.ToString = function
        | Point (x,y) -> sprintf "(%f; %f)" x y
        | Vector (x,y) -> sprintf "(%f; %f)" x y
        | Line ((x0,y0),(x1,y1)) -> sprintf "(%f; %f)->(%f; %f)" x0 y0 x1 y1
        | Circle ((x0,y0),radius) -> sprintf "(%f; %f)r%f" x0 y0 radius


let inline (-) (Point (x0,y0)) (Point (x1,y1)) = Vector (x0-x1,y0-y1) 
let inline (+) (Point (x0,y0)) (Vector (x1,y1)) = Point (x0+x1,y0+y1)

并且编译器说运算符的模式匹配并不详尽,尽管这只是一个警告。如何在没有编译器提示的情况下仅在 DU 的特定子类型之间正确实现运算符?

最佳答案

运算符通常定义为静态成员:

type shape =
    ...
    static member (-) (x, y) =
        match x, y with
        | Point (x0,y0), Point (x1,y1) -> Vector (x0-x1,y0-y1) 
        | Point (x0,y0), Vector (x1,y1) -> Point (x0+x1,y0+y1)
        | _ -> failwith "invalid arguments"

关于您的尝试的几点说明:

  1. 联合案例不是类型,因此不能用于定义方法重载
  2. 函数不能重载

关于f# - 如何在 f# 中为可区分联合定义运算符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17053368/

相关文章:

f# - 如何在 F# 中实现 Python 类

data-structures - List.permute 的性能

reflection - 使用 Reflection.Emit 生成可识别联合

Typescript Tagged Unions - 编译器可以警告您遗漏的分支案例吗?

xml - 如何使用 F# Data 的 XML 类型提供程序检索 XML 属性 "two nodes deep"?

f# - List.where 与 List.filter 相同吗?

可区分联合的 F# 限制

typescript - Typescript 中带有 bool 值的可区分联合

typescript - 给定判别式,获取判别联合的相应成员的属性类型

f# - 在 F# 中将 Int 转换为 Float 而不进行舍入