列表、IEnumerable 等上的 F# 扩展方法

发布于 2024-10-10 04:46:44 字数 517 浏览 0 评论 0原文

在 C# 中,如果我有一个小部件定义,比如说:

class widget
{
    public string PrettyName() { ... do stuff here }
}

并且我想允许轻松打印小部件列表,我可能会这样做:

namespace ExtensionMethods
{
    public static PrintAll( this IEnumerable<Widget> widgets, TextWriter writer )
    {
        foreach(var w in widgets) { writer.WriteLine( w.PrettyName() ) }
    }  
}

如何使用记录类型和集合(最好是 List 或 Seq)完成类似的事情F#)。我希望有一个 Widgest 列表,并且能够直接在集合上调用执行类似操作的函数。假设(因为它是 F#)该函数不会更改它所附加到的集合的状态,而是返回一些新值。

In C#, if I had a widget definition, say:

class widget
{
    public string PrettyName() { ... do stuff here }
}

and I wanted to allow for easy printing of a list of Widgets, I might do this:

namespace ExtensionMethods
{
    public static PrintAll( this IEnumerable<Widget> widgets, TextWriter writer )
    {
        foreach(var w in widgets) { writer.WriteLine( w.PrettyName() ) }
    }  
}

How would I accomplish something similar with a record type and a collection (List or Seq preferrably in F#). I'd love to have a list of Widgest and be able to call a function right on the collection that did something like this. Assume (since it's F#) that the function would not be changing the state of the collection that it's attached to, but returning some new value.

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

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

发布评论

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

评论(1

剑心龙吟 2024-10-17 04:46:44

F# 中不可能有完全类似的解决方案。 F# 扩展成员只能像原始类型上的成员一样进行定义,因此您可以在泛型类型 IEnumerable<'T> 上定义 F# 扩展,但不能在特定实例化(例如 IEnumerable

在 C# 中,扩展方法通常用于提供更流畅的编码风格(例如 myWidgets.PrintAll(tw))。在 F# 中,您通常只需定义一个 let 绑定函数并使用管道运算符即可实现类似的效果。例如:

module Widget =
  let printAll (tw:TextWriter) s =
    for (w:Widget) in s do
      writer.WriteLine(w.PrettyName())

open Widget
let widgets = // generate a sequence of widgets somehow
let tw = TextWriter()
widgets |> printAll tw

An exactly analogous solution isn't possible in F#. F# extension members can only be defined as if they were members on the original type, so you can define F# extensions on the generic type IEnumerable<'T>, but not on a specific instantiations such as IEnumerable<Widget>.

In C#, extension methods are often used to provide a more fluent coding style (e.g. myWidgets.PrintAll(tw)). In F#, you'd typically just define a let-bound function and use the pipeline operator to achieve a similar effect. For example:

module Widget =
  let printAll (tw:TextWriter) s =
    for (w:Widget) in s do
      writer.WriteLine(w.PrettyName())

open Widget
let widgets = // generate a sequence of widgets somehow
let tw = TextWriter()
widgets |> printAll tw
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文