¿Cómo hacer expresiones lambda multilínea en f #?
Pregunta
¿Cómo haría esto (C #) en F #
public class MyClass
{
void Render(TextWriter textWriter)
{
Tag(() =>
{
textWriter.WriteLine("line 1");
textWriter.WriteLine("line 2");
});
Tag(value =>
{
textWriter.WriteLine("line 1");
textWriter.WriteLine(value);
}, "a");
}
public void Tag(Action action)
{
action();
}
public void Tag<T>(Action<T> action, T t)
{
action(t);
}
}
Solución
Una lambda multilínea en F # es solo
(fun args ->
lots
of
code
here
)
Todo el código sería algo así como
open System.IO
type MyClass() as this =
let Render(tw : TextWriter) =
this.Tag(fun() ->
tw.WriteLine("line1")
tw.WriteLine("line2")
)
this.Tag(fun(value : string) ->
tw.WriteLine("line1")
tw.WriteLine(value)
, "a"
)
member this.Tag(action) =
action()
member this.Tag(action, x) =
action(x)
asumiendo que no cometí errores de transcripción. (Utilicé tipos de función F # en lugar de delegados de acción en la interfaz pública).
Otros consejos
Si todo lo que quiere hacer es escribir lambdas de varias líneas, puede encadenar varias declaraciones usando el operador de punto y coma entre paréntesis. Ejemplo:
(fun () -> (write_line "line 1" ; write_line "line 2"))
y
(fun val -> (write_line "line 1" ; write_line val))
Aunque el segundo ejemplo que di solo funciona si el tipo de val es string.
Advertencia: no sé los detalles de F #. Estoy escribiendo esto desde un fondo Objective Caml. Los idiomas son muy similares, pero puede haber algunas diferencias que hacen que mi sugerencia sea un poco incorrecta. Además, ahora no estoy en una máquina con un intérprete ocaml o F #, así que no puedo verificar estos fragmentos para asegurarme de que funcionen.