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
。
在 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
。