F# Métodos de extensión en listas, Ienumerables, etc.
-
14-10-2019 - |
Pregunta
En C#, si tuviera una definición de widget, diga:
class widget
{
public string PrettyName() { ... do stuff here }
}
Y quería permitir una fácil impresión de una lista de widgets, podría hacer esto:
namespace ExtensionMethods
{
public static PrintAll( this IEnumerable<Widget> widgets, TextWriter writer )
{
foreach(var w in widgets) { writer.WriteLine( w.PrettyName() ) }
}
}
¿Cómo lograría algo similar con un tipo de registro y una colección (lista o seq preferiblemente en f#)? Me encantaría tener una lista de Widgest y poder llamar a una función directamente en la colección que hizo algo como esto. Suponga (ya que es f#) que la función no estaría cambiando el estado de la colección al que está conectado, sino devolver algún valor nuevo.
Solución
Una solución análoga exactamente no es posible en F#. Los miembros de la extensión f# solo se pueden definir como si fueran miembros en el tipo original, por lo que puede definir las extensiones de F# en el tipo genérico IEnumerable<'T>
, pero no en instancias específicas como IEnumerable<Widget>
.
En C#, los métodos de extensión a menudo se usan para proporcionar un estilo de codificación más fluido (por ejemplo, myWidgets.PrintAll(tw)
). En F#, normalmente definiría una función de alquiler y usaría el operador de tubería para lograr un efecto similar. Por ejemplo:
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