F#类型成员是否可以相互引用?
我想知道是否有一种方法可以让类型成员相互引用。我想这样写下面的程序:F#类型成员是否可以相互引用?,f#,members,F#,Members,我想知道是否有一种方法可以让类型成员相互引用。我想这样写下面的程序: type IDieRoller = abstract RollDn : int -> int abstract RollD6 : int abstract RollD66 : int type DieRoller() = let randomizer = new Random() interface IDieRoller with member this.Rol
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
有什么建议吗?谢谢 尝试以下操作:
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#默认隐式实现接口):
如果类只是一个接口实现,那么可以使用对象表达式。如果可能的话,我更喜欢这个,因为它简洁
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 }
C#
我喜欢这样,但似乎我必须放弃名称空间,因为在使用名称空间时,不可能有浮动的,让我们在没有封闭类型的情况下使用。我想大概是这样因为我引用了C#中的代码,所以拥有它们真的很方便。不过,我意识到这超出了我在问题中提出的范围。你不必放弃名称空间。我更新了代码来演示。在F#和C#中可以让相同的API感觉非常自然。谢谢提示。这两种选择我都没有想到。:)但也不确定这两种方法是否更简洁。我想第一个是,但看起来确实更混乱。两个都不想比另一个更简洁;后一个版本的用法通常会更简洁。公平地说,我要求的是优雅而不是简洁。我打字的时候脑子有点乱。这两个词的用法不一样吗?@McMuttons:不,一点也不一样。使用前者,您不仅可以实例化一个
DieRoller
对象并调用其中任何一个方法;您首先必须转换到IDieRoller
。这就是我所说的“显式接口实现”。啊,好的,我明白你的意思了。谢谢你的解释。这两个答案都很好,但是我必须选择一个,然后选择一个可能更接近我的用法的答案。谢谢你的帮助!
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();