简体   繁体   English

通用F#运算符很有趣

[英]Generic F# operators fun

This question follows the idea posted here: Generic units in F# 此问题遵循此处发布的想法: F#中的通用单位

I've started wondering if that was possible to define a generic operator that accepts two arguments in a similar way, like it it presented in the post I linked ? 我开始怀疑是否可以定义一个通用运算符,以类似的方式接受两个参数,就像我链接的文章中介绍的那样?

For exapmple: I've been trying to implement an "AlmostEqual" operator (=~) that works with Floats and my own type, called "VectorDirection". 例如:我一直在尝试实现一个“ AlmostEqual”运算符(=〜),该运算符可与Floats和我自己的类型(称为“ VectorDirection”)一起使用。 Following the idea, I've created the following piece of code: 按照这个想法,我创建了以下代码:

type AlmostEqual = AlmostEqual with
    static member ($) (AlmostEqual, (a,b) : float * float) = a >= b - Math.tol && a <= b + Math.tol    
    static member ($) (AlmostEqual, (vd1, vd2)) =
                        // my logic goes here - irrelevant for the general idea presented here

let inline (=~) x = AlmostEqual $ x

That works fine, BUT with a serios limitation: it can be used in the following way: 可以,但是有血清限制,但是可以用以下方式使用:

(=~) (arg1, arg2)

That means the more natural way of using it: 这意味着更自然的使用方式:

arg1 =~ arg2  // wrong: (=~) complains it's in a wrong place and arg2 is not a tuple

is not allowed. 不被允许。 I understand the limitation, but I can't really find a way to walk it around. 我了解局限性,但是我真的找不到解决它的方法。

let inline (=~) (x,y) = ...

are a function there takes a tuple as its argument and 是一个以元组为参数的函数,

let inline (=~) x y = ...

are a function there takes two arguments. 是一个函数,需要两个参数。 If you want to use a function as a infix function it need to take two arguments. 如果要将函数用作中缀函数,则需要使用两个参数。

As explained in the other answer the problem is tupled vs. curried arguments, by defining your function like this will solve the main issue: 如另一个答案中所述,问题是元组与咖喱参数,通过这样定义函数将解决主要问题:

let inline (=~) x y = AlmostEqual $ (x, y)

Anyway I would advise you to change your members definition as well, because you may have problems with overload resolution by tupling the polymorphic arguments. 无论如何,我还是建议您更改成员定义,因为您可能会通过关联多态参数而在重载解析方面遇到问题。 If you run into these problems try this: 如果遇到这些问题,请尝试以下操作:

type AlmostEqual = AlmostEqual with
    static member ($) (AlmostEqual, a: float) = fun (b: float) -> // {your implementation}
    static member ($) (AlmostEqual, vd1     ) = fun vd2        -> // {your implementation}

let inline (=~) x y = (AlmostEqual $ x) y

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM