I was wondering if there is a way to let type members reference each other. I would like to write the following program like this:
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 is unable to see this.RollD6. I can sort of see why, but it seems most functional languages have a way of letting functions know that they exist ahead of time so that this or similar syntax is possible.
Instead I've had to do the following, which isn't much more code, but it seems that the former would look more elegant than the latter, especially if there are more cases like that.
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!
If the class is nothing more than an interface implementation, you can use an object expression. I prefer this, when possible, for its conciseness.
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 }
open MyNamespace.DieRoller
let dieRoller = makeDieRoller()
using MyNamespace;
var dieRoller = DieRoller.Create();
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, you may find the following easier to use (as F# implements interfaces explicitly, 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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With