Can members of type F # refer to each other?

I was wondering if there is a way for type members to refer to each other. I would like to write the following program as follows:

type IDieRoller = abstract RollDn : int -> int abstract RollD6 : int abstract RollD66 : int type DieRoller() = let randomizer = new Random() interface IDieRoller with member this.RollDn max = randomizer.Next(max) member this.RollD6 = randomizer.Next(6) member this.RollD66 = (RollD6 * 10) + RollD6 

But, this.RollD66 cannot see this.RollD6. I can understand why, but it seems that most functional languages ​​have a way to tell functions that they exist ahead of time so that this or similar syntax is possible.

Instead, I had to do the following, which is not much more code, but it seems that the former would look more elegant than the latter, especially if there are more such cases.

 type DieRoller() = let randomizer = new Random() let rollD6 = randomizer.Next(6) interface IDieRoller with member this.RollDn max = randomizer.Next(max) member this.RollD6 = rollD6 member this.RollD66 = (rollD6 * 10) + rollD6 

Any tips? Thanks!

+4
source share
2 answers

If the class is nothing more than an implementation of an interface, you can use an object expression. I prefer this, whenever possible, for its brevity.

 namespace MyNamespace type IDieRoller = abstract RollDn : int -> int abstract RollD6 : int abstract RollD66 : int module DieRoller = open System [<CompiledName("Create")>] let makeDieRoller() = let randomizer = new Random() { new IDieRoller with member this.RollDn max = randomizer.Next max member this.RollD6 = randomizer.Next 6 member this.RollD66 = this.RollD6 * 10 + this.RollD6 } 

F #

 open MyNamespace.DieRoller let dieRoller = makeDieRoller() 

WITH#

 using MyNamespace; var dieRoller = DieRoller.Create(); 
+6
source

Try the following:

 open System type IDieRoller = abstract RollDn : int -> int abstract RollD6 : int abstract RollD66 : int type DieRoller() = let randomizer = Random() interface IDieRoller with member this.RollDn max = randomizer.Next max member this.RollD6 = randomizer.Next 6 member this.RollD66 = (this :> IDieRoller).RollD6 * 10 + (this :> IDieRoller).RollD6 

However, it may seem to you that the following is easier to use (since F # explicitly implements interfaces, unlike C #, which implements them implicitly by default):

 open System type IDieRoller = abstract RollDn : int -> int abstract RollD6 : int abstract RollD66 : int type DieRoller() = let randomizer = Random() member this.RollDn max = randomizer.Next max member this.RollD6 = randomizer.Next 6 member this.RollD66 = this.RollD6 * 10 + this.RollD6 interface IDieRoller with member this.RollDn max = this.RollDn max member this.RollD6 = this.RollD6 member this.RollD66 = this.RollD66 
+6
source

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


All Articles