En este poste te voy a mostrar como puedes hacer composición de funciones en C#.
Primeros pasos.
La composición de funciones (function composition) es un mecanismo heredado del paradigma funcional que permite componer o encadenar una función a partir de otras.
Este mecanismo no es parte del framework, afortunadamente, puedes emularlo con métodos de extension y Funcs. C# soporta el uso de funciones como objetos desde hace tiempo.
Tienes dos opciones para evaluar la cadena, evaluar de izquierda a derecha, o viceversa:
- Compose: C ⇒ B ⇒ A
- AndThen: A ⇒ B ⇒ C
Cosas a tener en cuenta.
Este ejemplo solo evalúa funciones que tienen el mismo tipo de entrada y de salida, si necesitas resolver escenarios más complejos, quizá, te convenga descargar packages Nuget específicos como Language Extensions.
Ejemplo:
En el siguiente ejemplo hago uso de la composición de funciones al estilo de Scala. Con los métodos de extension Compose y AndThen. Descompuse la fórmula de cálculo del área del círculo en varias funciones, y las compuse para producir el resultado deseado.
using System; | |
Func<double, double> square = x => | |
{ | |
Console.WriteLine($"(A) Calculating square: {x}"); | |
return x * x; | |
}; | |
Func<double, double> multipliedByPi = x => | |
{ | |
Console.WriteLine($"(B) Multiplying by pi: {x}"); | |
return x * 3.14; | |
}; | |
Func<double, double> circleArea = multipliedByPi.Compose(square); | |
Func<double, double> anotherCircleArea = square.AndThen(multipliedByPi); | |
Console.WriteLine($"COMPOSE: Result of circleArea: {circleArea(10)}"); | |
Console.WriteLine($"AND THEN: Result of anotherCircleArea: {anotherCircleArea(8)}"); | |
//you can compose any function you want into a new one. | |
Console.WriteLine(circleArea.AndThen(x=> | |
{ | |
Console.WriteLine("(C) Adding 1"); | |
return x + 1; | |
}).Invoke(10)); | |
internal static class CompositionExtensions | |
{ | |
//AndThen A => B => C | |
public static Func<TA, TC> AndThen<TA, TB, TC>(this Func<TA, TB> left, Func<TB, TC> right) => | |
x => right.Invoke(left.Invoke(x)); | |
//Compose C => B => A | |
public static Func<TA, TC> Compose<TA, TB, TC>(this Func<TB, TC> left, Func<TA, TB> right) => | |
x => left.Invoke(right(x)); | |
} |
Referencias:
- NVL in SQL Server - 2023-11-01
- ¿Que es Cake Build? - 2023-02-22
- #How to fix error: MSB4019: The imported project «Microsoft.Data.Tools.Schema.SqlTasks.targets» was not found - 2023-02-20