DRY自复制型

DRY self-replicating type

在 F# 中是否有表达自复制类型的简洁方法? ——即不再赘述。

// Manual self-replication

type Foo (par1 : Type1, par2 : Type2, par3 : Type3, par4 : Type4) =

    let unique = new UniqueState() // unique for every instance of Foo

    member this.SelfReplicate =
        new Foo(par1, par2, par3, par4) // repeating myself

let a = new Foo(x, y, z, w)
let b = a.SelfReplicate

尝试使用手动注入的自我复制器:

// Semi-automagic self-replication

type Foo' (par1 : Type1, par2 : Type2, par3 : Type3, par4 : Type4, replicate : unit -> Foo') =

    let unique = new UniqueState() // unique for every instance of Foo'

    member this.SelfReplicate = replicate() // not repeating myself

let rec foo' () = new Foo'(x, y, z, w, foo')
let a = foo'()
let b = a.SelfReplicate

如果没有编译器魔法,我不确定这怎么能更简洁。似乎应该有一种方法可以捕获当前参数和类型,而无需在语法上重复它们。

您可以定义一个类型 WithUnique<'T>,它是对类型 'T 的值的包装,并向其添加一个唯一值。您可能需要考虑如何对这些类型进行相等性测试 - 如果您使用记录(正如我在下面所做的那样),那么具有不同唯一值的两个实例将不相等:

let rnd = System.Random()
let uniqueState() = rnd.Next()

type WithUnique<'T> = 
  { Value : 'T; Unique : int }
  static member Create(v) : WithUnique<'T> = 
    { Value = v; Unique = uniqueState() }
  member x.Replicate() = 
    { Value = x.Value; Unique = uniqueState() }

'T的值只是一种类型,但如果你需要包装多个东西,这可以是一个元组(或记录):

let wu1 = WithUnique.Create( (10, "hi") )
let wu2 = wu1.Replicate()

鉴于上述情况,wu1=wu2 将是 false