F # Continuous Interop Class

How F # immutable types interact with C #. I'm just starting to learn F #, and I would like to mix it with some C # code that I have, but I want my F # classes to be immutable.

Say we create a Vector class in F #. Vector.X and Vector.Y must be re-assignable, but only must return a new Vector class. In C #, this will require the allocation of elements to work. Thanks (float x) clone an existing object and return a new one. Is there an easy way to do this in F #?

I searched for a while, and I can not find any documents about this. So any help would be great.

And finally, if I imported this class into C #, what would its interface look like? Will the F # code restrict me from doing something stupid like Vector.X = 10 ?

+4
source share
2 answers

It will look the same whether C # or F #.

You say: β€œIn C # it will work”, but cmon, I think

 Vector WithX(float x) { return new Vector(x, this.Y); } 

it is right?

In both C # and F #, to prevent the assignment of the X property, you create the property using "getter", but not "setter".

I think you make it all more difficult than it is, or maybe I don’t understand what you are asking.

EDIT

For the case (I think it’s rare), where there are 20 fields, and you may want to change only a small arbitrary subset of them, I found a nice hack to make good use of the F # and C # parameters.

F # Code:

 namespace global open System.Runtime.InteropServices type Util = static member Some<'T>(x:'T) = Some x type MyClass(x:int, y:int, z:string) = new (toClone:MyClass, [<Optional>] ?x, [<Optional>] ?y, [<Optional>] ?z) = MyClass(defaultArg x toClone.X, defaultArg y toClone.Y, defaultArg z toClone.Z) member this.X = x member this.Y = y member this.Z = z 

Customer Code F #:

 let a = new MyClass(3,4,"five") let b = new MyClass(a, y=44) // clone a but change y 

C # client code:

 var m = new MyClass(3, 4, "five"); var m2 = new MyClass(m, y:Util.Some(44)); // clone m but change y 

That is, optional parameters are a good way to do this, and while additional C # parameters have some limitations, you can provide additional F # parameters in such a way that this is normal with C #, as suggested above.

+8
source

F # Record types have a built-in way to do exactly what you ask for:

 type Vector = {X:float; Y:float} let v1 = {X=1.; Y=2.} let v2 = {v1 with X=3.} 

How this happens with C #, I'm not sure (edit: see Brian's comment).

The vector will be unchanged from any .NET language, since X and Y are implemented as getters without setters.

+6
source

Source: https://habr.com/ru/post/1337050/


All Articles