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

クラスがインターフェイスの実装にすぎない場合は、オブジェクト式を使用できます。可能であれば、その簡潔さのためにこれを好みます。

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 に答える
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

ただし、次のほうが使いやすい場合があります (デフォルトで暗黙的に実装する C# とは異なり、F# はインターフェイスを明示的に実装するため)。

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 に答える