F#中的循环功能/类型依赖性 [英] Cyclic function/type dependency in F#

查看:69
本文介绍了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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆