2012-01-23 6 views
9
public static Func<V> To<T, V>(this Func<T> g, Func<T, V> h) 
{ 
    return() => h(g()); 
} 

public static Func<T> ToIdentity<T>(this T t) 
{ 
    return() => t; 
} 

A veces uso estos y otros para retrasar la evaluación. ¿Ya están en la biblioteca .net?¿Ya existen construcciones funcionales C# /. NET como estas? g (h()) o

Editar:

Aquí es un ejemplo de uso:

public static string SuffixColumn(this string v, string suffix, int columns) 
{ 
    return 
    v.ToIdentity() 
     .ToScrubbedHtml() 
     .ToFormat(() => "{0} " + suffix.ToLower().PadLeft(columns, ' ')) 
     .ToErrorText(v, suffix, columns)(); 
} 

ToErrorText cheques 'V' como (código de no error, no nulo, etc) legítimo, si bien que se corre el encadenado en Func, si es malo produce un resultado de texto a prueba de fallas. Si v, sufijo o columnas no son buenos, nunca se llamará ToFormat. (De ahí el uso retrasado/no evaluado).

ToFormat es casi la composición de la Func y cadena proporcionadas. Formato. ToIdentity se usa para levantar v a un Func y luego todo en la cadena se basa en algunos Func de T.

+1

¿cómo retrasar la evaluación utilizando el código proporcionado? – Tigran

+3

La respuesta corta es no. Sin embargo, tengo curiosidad. Estos son combinadores bastante inusuales ya que devuelven métodos que no toman argumentos. ¿Para qué los estás usando? Además, este último está mal nombrado; una función de identidad tiene la propiedad de que su entrada es igual a su salida, pero la función devuelta aquí no toma entradas. –

+0

Gracias por los comentarios: no estoy muy seguro de a qué otra cosa llamar ToIdentity. Y To() probablemente debería llamarse Compose. Pero cada resultado en una función que no toma ningún argumento, por lo que no es exactamente lo mismo. – lucidquiet

Respuesta

34

Vamos a ver si lo entiendo: usted está usando lambdas para capturar valores en un objeto "contenedor" - un Func<T> - y luego construir un flujo de trabajo de funciones evaluadas con pereza-envuelta alrededor del objeto, ¿verdad?

enter image description here

Aunque la construcción fuera de funciones funciona, yo personalmente se inclinaría a construir la mónada de algún tipo personalizado; parece demasiado fácil combinar las funciones que actúan sobre el tipo monádico o su tipo "subyacente" con instancias de la mónada en sí. Básicamente está construyendo la mónoma de identidad usando funciones; Me inclinaría más a simplemente crear una clase o interfaz con un nombre que refleje el propósito para el que está poniendo la mónada de identidad.

También podría considerar cambiar el nombre de sus métodos. Su "A" se llama tradicionalmente "Enlace" y su "ToIdentity" se denomina tradicionalmente "Unidad".

Es decir, un patrón mónada para un tipo mónada M<T> por lo general tiene los métodos:

public static M<V> Bind<U, V>(this M<U> m, Func<U, M<V>> k) 

y

public static M<T> Unit<T>(this T value) 

El unen permite implementar la composición de funciones en mónadas que son análogas a funciones que componen los tipos "subyacentes" de las mónadas.

Para una suave introducción a las maravillas de mónadas en C#, consulte gran artículo de mi compañero de trabajo antiguo Wes Dyer sobre el tema:

http://blogs.msdn.com/b/wesdyer/archive/2008/01/11/the-marvels-of-monads.aspx

Para responder a su pregunta fue:

¿Ya están en la biblioteca .net?

Esas funciones exactas no están en el marco. Pero funciones muy similares a las que existen en el marco. Por ejemplo, SelectMany en IEnumerable<T> es análogo a su método To; implementa la operación de enlace monádico en secuencias. new Nullable<int>(123) es análogo a su método "ToIdentity"; implementa la operación de la unidad monádica para la "tal vez mónada". Y así.

El sistema de tipo CLR no es lo suficientemente rico para expresar el patrón de mónada en general; para eso necesitas un sistema de tipo "superior", como el de Haskell. Tendrás que construir cada mónada específica por ti mismo. Sin embargo, parece que estás en camino.

algunos pensamientos más sobre el uso de las mónadas en C# -como idiomas:

Monads in C# -- why Bind implementations require passed function to return a monad?

Monad in plain English? (For the OOP programmer with no FP background)

Why there is no something like IMonad<T> in upcoming .NET 4.0

Help a C# developer understand: What is a monad?

+0

Inteligente para reconocer estos en una forma disfrazada. – jason

+9

lol en clippy: D –

+0

Ahora hay una característica que VS realmente necesita obtener. XCode y Eclipse nunca podrían competir. – MgSam

2

Puede usar Lazy para valores de carga lenta.

Lazy<int> lazy = new Lazy<int>(() => delayEvaluatingMe()); 
int delayed = lazy.Value; 
+0

Esto ni siquiera responde la pregunta. – jason

Cuestiones relacionadas