How to implement (<=) : MyExpr -> MyExpr -> MyExpr

Answered How to implement (<=) : MyExpr -> MyExpr -> MyExpr

  • Thursday, October 06, 2011 2:45 PM
     
      Has Code

    > Can you elaborate on the problem with comparison operators? Why not implement IComparable as the warnings suggest?

     > Or else just make the operators traditional functions that take arguments of Expr/ExprA?

     

    What I need is to overload (<=) like a normal operator (say ++) and make it return a sum value Leq (x, y) of type MyExpr

    Variable "x" <= 3

    val it : ConstraintI = Leq (Variable "x", Constant 3.0)

    I don't see how I could implement IComparable which has a different signature : 'a -> 'a -> int

    The compiler doesn't complain if I use any other symbol than <= like <<=

    let inline (<=) x y = ((^a or ^b): (static member (<=) : ^a * ^b -> ^c) (x,y))
    
    type constraintI =
        | Equal of exprI * exprI
        | Leq of exprI * exprI
        | Geq of exprI * exprI
    and  exprI =
        | Constant of float
        | Plus of exprI * exprI
        | Minus of exprI * exprI
        | Times of exprI * exprI
        | Variable of string
        static member (+) (i : int, e) = Plus (Constant (float i), e)
        static member (+) (e, i : int) = Plus (Constant (float i), e)
        static member (+) (f : float, e) = Plus (Constant f, e)
        static member (+) (e, f : float) = Plus (Constant f, e)
        static member (+) (e1, e2) = Plus (e1, e2)
    
        static member (-) (i : int, e) = Minus (Constant (float i), e)
        static member (-) (e, i : int) = Minus (e, Constant (float i))
        static member (-) (f : float, e) = Minus (Constant f, e)
        static member (-) (e, f : float) = Minus (e, Constant f)
        static member (-) (e1, e2) = Minus (e1, e2)
        
        static member (*) (i : int, e) = Times (Constant (float i), e)
        static member (*) (e, i : int) = Times (Constant (float i), e)
        static member (*) (f : float, e) = Times (Constant f, e)
        static member (*) (e, f : float) = Times (Constant f, e)
        static member (*) (e1, e2) = Times (e1, e2)
    
        static member (==) (i : int, e) = Equal (e, Constant (float i))
        static member (==) (e, i : int) = Equal (e, Constant (float i))
        static member (==) (f : float, e) = Equal (e, Constant f)
        static member (==) (e, f : float) = Equal (e, Constant f)
        static member (==) (e1, e2) = Equal (e1, e2)
    
        static member (<=) (i : int, e) = Leq (Constant (float i), e)
        static member (<=) (e, i : int) = Leq (e, Constant (float i))
        static member (<=) (f : float, e) = Leq (Constant f, e)
        static member (<=) (e, f : float) = Leq (e, Constant f)
        static member (<=) (e1, e2) = Leq (e1, e2)
    
        static member (>=) (i : int, e) = Geq (Constant (float i), e)
        static member (>=) (e, i : int) = Geq (e, Constant (float i))
        static member (>=) (f : float, e) = Geq (Constant f, e)
        static member (>=) (e, f : float) = Geq (e, Constant f)
        static member (>=) (e1, e2) = Geq (e1, e2)
    
    (Variable "x") <= 3
    
    


All Replies

  • Thursday, October 06, 2011 5:20 PM
     
     Answered

    Hi Diego,

    You should use another symbol. F# operators <, <=, >, >=, = and <> are generic (via IComparable) rather than using adhoc overloading.

     

    Thanks

    don