Failed to extend statements in F #?

module FSharp= let Point2d (x,y)= Point2d(x,y) let Point3d (x,y,z)= Point3d(x,y,z) type NXOpen.Point3d with static member ( * ) (p:Point3d,t:float)= Point3d(pX*t,pY*t,pZ*t) static member ( * ) (t:float,p:Point3d)= Point3d(pX*t,pY*t,pZ*t) static member (+) (p:Point3d,t:float)= Point3d(p.X+t,p.Y+t,p.Z+t) static member (+) (t:float,p:Point3d)= Point3d(p.X+t,p.Y+t,p.Z+t) static member (+) (p:Point3d,t:Point3d)= Point3d(p.X+tX,p.Y+tY,p.Z+tZ) let a=Point3d (1.,2.,3.) let b=1.0 let c=a * b//error 

Error 15: Type "float" does not match type
'Point3d' E: \ Work \ extension-RW \ VS \ extension \ NXOpen.Extension.FSharp \ Module1.fs 18 13 NXOpen.Extension.FSharp

I want to extend Point3d methods, some new operators. But this does not work.

+3
operators extension-methods f #
Nov 29 '11 at 10:59
source share
2 answers

In fact, it is possible. There is a way to extend binary operators using a single and little-known ternary operator ?<- . Therefore, in your case, you can try the following:

 type SumPoint3d = SumPoint3d with static member (?<-) (p:Point3d, SumPoint3d, t ) = Point3d(pX + t , pY + t , pZ + t ) static member (?<-) (t , SumPoint3d, p:Point3d) = Point3d(pX + t , pY + t , pZ + t ) static member (?<-) (p:Point3d, SumPoint3d, t:Point3d) = Point3d(pX + tX, pY + tY, pZ + tZ) static member inline (?<-) (a , SumPoint3d, b ) = a + b type ProdPoint3d = ProdPoint3d with static member (?<-) (p:Point3d, ProdPoint3d, t ) = Point3d(pX * t, pY * t, pZ * t) static member (?<-) (t , ProdPoint3d, p:Point3d) = Point3d(pX * t, pY * t, pZ * t) static member inline (?<-) (a , ProdPoint3d, b ) = a * b let inline ( + ) ab = a ? (SumPoint3d ) <- b let inline ( * ) ab = a ? (ProdPoint3d) <- b let a=Point3d (1.,2.,3.) let b=1.0 

Now you can try:

 > let c=a * b ;; val c : Point3d = Point3d (1.0,2.0,3.0) > 2 * 3 ;; val it : int = 6 
+3
Nov 30 '11 at 13:45
source share

If the Point3d type Point3d declared in a separate assembly that you cannot change, then, unfortunately, there is no way to implement new overloads of standard operators, such as + or * . The code in your question adds operators as extension methods, but the F # compiler does not look for extension methods when looking for overloaded operators.

If you cannot change the library, then you can do three things:

  • Create a wrapper for Point3d that stores the value of Point3d and implements all the operators
    (but it will probably be quite inefficient)

  • Identify new operators that do not interfere with the built-in ones. For example, you can use +$ and $+ to multiply by scalar left and right. To declare such an operator, you must write:

     let (+$) (f:float) (a:Point3d) = (...) 
  • Point3d type that does all the work, perhaps with a conversion function that turns it into Point3d when you need to call the library.

It's hard to say which option is better - the second approach is probably the most effective, but it will make the code a little ugly. Depending on your scenario, option 1 or 3 may also work.

+5
Nov 29 '11 at 11:54
source share



All Articles