F#中的循环功能/类型依赖性 [英] Cyclic function/type dependency in F#
问题描述
我对解决以下问题的最佳方法有疑问
I have a question about the best way to go about the following
我有一个B类,我有一个B组合器, let foo:B-> int.
I Have a class B, I have a combinator on B, let foo : B -> int.
我希望B类将组合器封装为一种方法,因此我将其添加为类型扩展.
I want the class B to have the combinator encapsulated as a method, so I add it with a type extension.
然后我后来意识到foo非常昂贵,并希望通过惰性评估来缓存它的结果
I then later on realize that foo is quite expensive and want to cache it's result with lazy evaluation
因此,我通过将组合器作为函数传递给构造函数,然后在构造函数中使用foo = lazy(foo self)初始化字段,从而给系统增加了巨大的负担.
So I add a huge clutch to the system by passing the combinator as a function to the constructor and then initializing a field with foo = lazy(foo self) in the constructor.
即
type foo =
class
val x : int Lazy
new (comb) as self = {x=lazy(comb self);}
end
let something (x:foo) = 1
type foo with
new() = foo(something)
这显然感觉不对
我看到的两个解决方案是:1,创建一个接口,让foo继承该接口,2,将所有内容变成一个静态方法,然后使这些组合器脱离这些静态方法(将它们附加到类上的相反做法) ...)
the two options I see for fixing this are 1, make an interface and have foo inherit that interface, 2, make everything a static method and then make combinators out of those static methods(sort of the opposite of attaching them to classes...)
这些都不是很吸引人,我想知道我是否错过了选项3
Neither of these are hugely appealing and I was wondering if I missed option 3
哦,我一直无法让let rec正常工作,我也不想真的因为上述声明中的某事"取决于一个函数,该函数取决于一个函数,该函数取决于一个函数(深度为3).
Oh, and I haven't been able to get let rec and to work quite right with this, nor would i really want to as "something" in the above statement depends on a function that depends on a function that depends on a function(3 deep).
任何建议将不胜感激
推荐答案
我认为您当前的设计没有任何问题.关键是,如果您在同一文件(和同一模块)中定义类型Foo
以及该类型的扩展名,则F#将把定义的两个部分组合为单个.NET类型.因此,它在两个单独的部分中定义的事实只是实现细节.
I don't think there is anything wrong with your current design. The key point is that if you define the type Foo
as well as the extension to the type in a same file (and the same module), then F# will combine the two parts of the definition into a single .NET type. So, the fact that it is defined in two separate parts is just an implementation detail.
如果您不想公开采用组合器的构造函数,则可以将其标记为private
.加上一些其他更改(即使用隐式构造函数语法),该代码段将如下所示:
If you don't want to expose the constructor that takes the combinator, you can mark it as private
. Together with a few additional changes (i.e. use implicit constructor syntax), the snippet would look like this:
type Foo private (comb) as self =
let x : Lazy<int> = lazy comb self
let something (x:Foo) = 1
type Foo with
new() = Foo(something)
如果您想将something
保留为单独的功能,那么这是一个很好的解决方案. F#PowerPack中的许多数字类型都遵循这种模式(例如,参见定义复数)
If you want to keep something
as a separate function, then this is a fine solution. Many numeric types in the F# PowerPack follow this pattern (see for example definition of complex numbers)
这篇关于F#中的循环功能/类型依赖性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!