F# 中的循环函数/类型依赖

发布于 2024-10-30 18:43:47 字数 709 浏览 5 评论 0原文

我有一个关于执行以下操作的最佳方法的问题

我有一个 B 类,我在 B 上有一个组合器, 让 foo : B ->国际。

我希望 B 类将组合器封装为方法,因此我添加了类型扩展。

后来我意识到 foo 相当昂贵,并且想要通过惰性求值缓存它的结果

所以我通过将组合器作为函数传递给构造函数,然后使用 foo = lazy(foo self 初始化一个字段,为系统添加了一个巨大的离合器)在构造函数中。

即,

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,将所有内容都设为静态方法,然后从这些静态方法中创建组合器(与附加它们相反)去上课...)

这些都不是非常有吸引力,我想知道我是否错过了选项 3

哦,而且我还没有能够得到让REC并正确地处理这个问题,我也不想像“上述语句中的“某物”依赖于一个函数,该函数又依赖于一个函数,而该函数又依赖于一个函数(深度为 3)。

任何建议将不胜感激

I have a question about the best way to go about the following

I Have a class B, I have a combinator on B,
let foo : B -> int.

I want the class B to have the combinator encapsulated as a method, so I add it with a type extension.

I then later on realize that foo is quite expensive and want to cache it's result with lazy evaluation

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.

i.e.

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)

this obviously feels wrong

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...)

Neither of these are hugely appealing and I was wondering if I missed option 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).

any advice would be appreciated

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

醉南桥 2024-11-06 18:43:47

我不认为你目前的设计有什么问题。关键点是,如果您在同一文件(和同一模块)中定义类型 Foo 以及该类型的扩展,那么 F# 会将定义的两部分合并为一个.NET 类型。因此,它被定义为两个单独的部分这一事实只是一个实现细节。

如果您不想公开采用组合器的构造函数,可以将其标记为private。加上一些额外的更改(即使用隐式构造函数语法),代码片段将如下所示:

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 中的许多数字类型都遵循此模式(例如,请参阅复数的定义< /a>)

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.

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)

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)

南渊 2024-11-06 18:43:47

我不太明白你想要什么,但我认为这可能会有所帮助:

type foo(comb) as self =
    let x = lazy(comb self)
    static member something (x:foo) = 1 
    new() = foo(foo.something)

类型可以用它自己的静态成员递归,所以这是编写代码的更简单的方法。

I don't quite grok what you're after, but I think this may help:

type foo(comb) as self =
    let x = lazy(comb self)
    static member something (x:foo) = 1 
    new() = foo(foo.something)

A type can be recursive with its own static member, so this is a simpler way to write your code.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文