2009-11-10 6 views
28

... con todos los nuevos (y no tan nuevo si contamos IEnumerable) cosas relacionadas mónada-?¿Por qué no hay algo así como IMonad <T> en la próxima .NET 4.0

interface IMonad<T> 
{ 
SelectMany/Bind(); 
Return/Unit(); 
} 

Eso permitiría escribir funciones que operan en cualquier tipo monádico. ¿O no es tan crítico?

+5

Eric Lippert explica por qué algunas características no están implementadas en el marco: http://stackoverflow.com/questions/1331739/enum-type-constraints-in-c/1331811#1331811 –

Respuesta

61

Piense acerca de lo que la firma de IMonad<T> 's métodos tendría que ser. En Haskell la clase de tipos Monad se define como

class Monad m where 
    (>>=) :: m a -> (a -> m b) -> m b 
    return :: a -> m a 

Es difícil de traducir esta directamente a una interfaz de C# porque es necesario para poder hacer referencia al subtipo particular de aplicación ("ma" o ISpecificMonad<a>) dentro de la definición de lo general Interfaz IMonad. Aceptar, en lugar de tratar de tener (por ejemplo) IEnumerable<T> implemento IMonad<T> directamente, vamos a tratar de factorizar la implementación IMonad a cabo en un objeto separado que se puede pasar, junto con la instancia de tipo mónada específica, a lo que hay que tratarlo como una mónada (esto es "estilo de paso de diccionario"). Esto será IMonad<TMonad> y TMonad aquí no será la T en IEnumerable<T>, pero sí IEnumerable<T>. Pero espera - esto tampoco puede funcionar, porque la firma de Return<T> por ejemplo tiene que llevarnos desde cualquier tipo T a un TMonad<T>, para cualquierTMonad<>. IMonad tendría que ser definido como algo parecido a

interface IMonad<TMonad<>> { 

    TMonad<T> Unit<T>(T x); 
    TMonad<U> SelectMany<T, U>(TMonad<T> x, Func<T, TMonad<U>> f); 
} 

utilizando una hipotética característica C# que nos permitirá usar constructores de tipo (como TMonad <>) como parámetros de tipo genérico. Pero, por supuesto, C# no tiene esta característica (polimorfismo de alto grado). Puede reificar constructores de tipo en tiempo de ejecución (typeof(IEnumerable<>)) pero no puede hacer referencia a ellos en las firmas de tipo sin darles los parámetros. Por lo tanto, además del punto -100 puntos, implementar esto "correctamente" requeriría no solo agregar otra definición de interfaz ordinaria, sino adiciones profundas al sistema de tipo.

Es por eso que la capacidad de tener consultas de comprensión sobre sus propios tipos es pirateada (simplemente funcionan "mágicamente" si los nombres de métodos mágicos correctos con las firmas correctas están ahí) en lugar de usar el mecanismo de interfaz, etc.

+10

Buena respuesta, Aquí hay una versión corta: "es imposible definir una Mónada en C#, el sistema de tipos no es lo suficientemente potente" :) –

+0

Por lo tanto, tal vez en CLR 5.0 o 6.0 o en un tiempo de ejecución de .NET posterior de mayor nivel de abstracción. –

+2

En mi opinión personal, sin efectos secundarios controlados estáticamente (es decir, funciones puras) se alcanza un punto de rendimientos severamente disminuidos al agregar más sofisticación al sistema de tipos bastante rápido. El beneficio real de un sistema de tipo sofisticado es poder establecer propiedades complejas/invariantes de su programa que, como se ha comprobado, son válidas en todos los casos (en lugar de probarse para ciertos casos y extrapolarlas heurísticamente a partir de allí), pero si alguna función tiene un "canal" adicional sin restricciones para la entrada/salida que no está marcada por el sistema de tipos, no hay mucho que pueda probar. –

-18

Las mónadas simplemente no son importantes para los programadores de .NET. Sin siquiera saber que existen mónadas, puedes construir el marco LINQ. Más importante aún, no se vería diferente. No importa si se piensa en términos de mónadas (Haskell), reescritura del árbol de expresiones (Lisp), operaciones basadas en conjuntos (SQL) o usando map/reduce para crear nuevos tipos (Ruby, Python), el resultado final es va a ser lo mismo.

De hecho, me gustaría ir tan lejos como para decir que las mónadas son francamente inútil para los desarrolladores de .NET. Cada vez que veo una biblioteca para .NET basada en mónadas, invariablemente es más detallada y menos comprensible que el código directo C# o VB. La razón es simple, los lenguajes como C# y VB están construidos en bloques de construcción mucho más poderosos que los lenguajes como Haskell.

Haskell en particular, tiene que usar mónadas para todo, porque eso es todo lo que tienen. Lo mismo ocurre con las macros en Lisp o la escritura dinámica en JavaScript. Cuando tienes un pony de un solo truco, ese truco tiene que ser bastante bueno.

On LINQ, Monads, and the Blindness of Power

+15

_ "La razón es simple, los lenguajes como C# y VB están construidos sobre bloques de construcción mucho, mucho más poderosos que los lenguajes como Haskell." Diciendo eso demuestra que nunca has programado en Haskell o aprendido sus conceptos por completo. –

+2

Merece anotaciones, solo por incluir un enlace a "blog privado". –

+1

Esto no merece ser votado negativamente. La pregunta exige una opinión obstinada de todos modos. Dio razones válidas contra una mónada en C#. – usr

Cuestiones relacionadas