4

我想知道是否有办法让类型成员相互引用。我想像这样编写以下程序:

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

但是,this.RollD66 无法看到 this.RollD6。我可以理解为什么,但似乎大多数函数式语言都有一种让函数提前知道它们存在的方法,因此这种或类似的语法是可能的。

相反,我必须执行以下操作,这不是更多代码,但似乎前者看起来比后者更优雅,特别是如果有更多这样的情况。

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

有小费吗?谢谢!

4

2 回答 2

6

尝试以下操作:

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

但是,您可能会发现以下更易于使用(因为 F# 显式实现接口,与默认情况下隐式实现它们的 C# 不同):

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
于 2011-04-07T19:00:43.703 回答
6

如果类只不过是一个接口实现,则可以使用对象表达式。如果可能的话,我更喜欢它,因为它简洁。

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()

C#

using MyNamespace;
var dieRoller = DieRoller.Create();
于 2011-04-07T19:44:55.047 回答