对集合类型进行抽象
除了使用 seq 模块之外,是否有可能编写关于它们支持的集合类型的通用函数?
目标是在添加新的集合功能时不必诉诸复制和粘贴。
Is there a possibility of writing functions which are generic in respect to collection types they support other than using the seq
module?
The goal is, not having to resort to copy and paste when adding new collection functions.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
使用集合进行泛型编程的处理方式与一般进行泛型编程的方式相同:使用泛型。
有点丑陋和冗长,但这是可能的。我使用类和静态成员来利用重载。在您的代码中,您只需使用 AF 即可调用正确的专业化。
对于更漂亮的解决方案,请参阅https://stackoverflow.com/questions/ 979084/what-features-would-you-add-remove-or-change-in-f/987569#987569 虽然此功能仅针对核心库启用,修改编译器以允许它出现在代码中应该不是问题。这是可能的,因为编译器的源代码是开放的。
Generic programming with collections can be handled the same way generic programming is done in general: Using generics.
A bit ugly and verbose, but it's possible. I'm using a class and static members to take advantage of overloading. In your code, you can just use A.F and the correct specialization will be called.
For a prettier solution, see https://stackoverflow.com/questions/979084/what-features-would-you-add-remove-or-change-in-f/987569#987569 Although this feature is enabled only for the core library, it should not be a problem to modify the compiler to allow it in your code. That's possible because the source code of the compiler is open.
seq<'T>
类型是编写适用于 F# 中任何集合的计算的主要方式。您可以通过多种方式使用该类型:Seq
模块中的函数(例如Seq.filter
、Seq.windowed 等)
seq { for x in col -> x * 2 }
)IEnumerator<'T>类型,有时需要该类型,例如,如果您想实现自己的集合压缩(这是通过调用 GetEnumerator 返回的),
这是相对简单的类型,只能用于从集合中读取数据。结果,您将始终获得
seq<'T>
类型的值,它本质上是一个惰性序列。F# 没有任何转换集合的机制(例如将集合
C
转换为具有新值的集合C
的通用函数)或任何创建集合的机制(Haskell 中提供)或斯卡拉)。在大多数实际情况下,我没有发现问题 - 大部分工作可以使用 seq<'T> 完成,并且当您需要专门的集合(例如用于性能的数组)时,无论如何,您通常需要稍微不同的实现。
The
seq<'T>
type is the primary way of writing computations that work for any collections in F#. There are a few ways you can work with the type:Seq
module (such asSeq.filter
,Seq.windowed
etc.)seq { for x in col -> x * 2 }
)IEnumerator<'T>
type, which is sometimes needed e.g. if you want to implement your own zipping of collections (this is returned by callingGetEnumerator
)This is relatively simple type and it can be used only for reading data from collections. As the result, you'll always get a value of type
seq<'T>
which is essentially a lazy sequence.F# doesn't have any mechanism for transforming collections (e.g. generic function taking collection
C
to collectionC
with new values) or any mechanism for creating collections (which is available in Haskell or Scala).In most of the practical cases, I don't find that a problem - most of the work can be done using
seq<'T>
and when you need a specialized collection (e.g. array for performance), you typically need a slightly different implementation anyway.