2009-11-10 11 views
28

... avec toutes ces nouvelles (et pas si nouvelles si on compte IEnumerable) liées à monad?Pourquoi il n'y a pas quelque chose comme IMonad <T> dans les prochains .NET 4.0

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

Cela permettrait d'écrire des fonctions qui fonctionnent sur n'importe quel type monadique. Ou ce n'est pas si critique?

+5

Eric Lippert explique pourquoi certaines fonctionnalités ne sont pas mises en œuvre dans le cadre: http://stackoverflow.com/questions/1331739/enum-type-constraints-in-c/1331811#1331811 –

Répondre

61

Pensez à ce que devrait être la signature pour les méthodes de IMonad<T>. Dans Haskell la classe de types Monad est défini comme

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

Il est difficile de traduire directement à une interface C# parce que vous devez être en mesure de faire référence au sous-type mise en œuvre spécifique (« ma » ou ISpecificMonad<a>) dans la définition du général Interface IMonad. OK, au lieu d'essayer (par exemple) IEnumerable<T> d'implémenter IMonad<T> directement, nous essaierons de factoriser l'implémentation IMonad en un objet séparé qui peut être passé, avec l'instance de type monad spécifique, à tout ce qui doit le traiter comme un monad (c'est "style de passage de dictionnaire"). Ce sera IMonad<TMonad> et TMonad ici ne sera pas le T en IEnumerable<T>, mais IEnumerable<T> lui-même. Mais attendez - cela ne peut pas fonctionner non plus, parce que la signature de Return<T> par exemple doit nous obtenir de tout de type T à un TMonad<T>, pour TMonad<>. IMonad devrait être définie comme quelque chose comme

interface IMonad<TMonad<>> { 

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

en utilisant une fonction hypothétique C# qui nous permettrait d'utiliser constructeurs de type (comme TMonad <>) en tant que paramètres de type générique. Mais bien sûr, C# n'a pas cette fonctionnalité (polymorphisme plus élevé). Vous pouvez réifier les constructeurs de type lors de l'exécution (typeof(IEnumerable<>)) mais ne pouvez pas les référencer dans les signatures de type sans leur donner de paramètres. Donc, en plus de la chose -100 points, l'implémentation de ce "correctement" nécessiterait non seulement l'ajout d'une autre définition d'interface ordinaire, mais des ajouts profonds au système de types. C'est pourquoi la possibilité d'avoir des requêtes sur vos propres types est piratée (elles fonctionnent simplement "magiquement" si les bonnes méthodes magiques avec les bonnes signatures sont présentes) au lieu d'utiliser le mécanisme d'interface, etc.

+10

Bonne réponse, voici une version courte: "il est impossible de définir une Monade en C#, le système de type n'est pas assez puissant" :) –

+0

Donc, peut-être dans CLR 5.0 ou 6.0 ou dans un runtime post .NET de plus haut niveau d'abstraction. –

+2

De mon point de vue personnel, sans effets secondaires statiquement vérifiés (c'est-à-dire des fonctions pures) vous avez atteint un point de rendements sévèrement décroissants en ajoutant plus de sophistication au système de type plutôt rapidement. Le vrai avantage d'un système de type sophistiqué est de pouvoir établir des propriétés/invariants complexes de votre programme qui sont prouvés dans tous les cas (au lieu d'être testés pour certains cas et extrapolés heuristiquement à partir de là), mais a un "canal" supplémentaire sans restriction pour les entrées/sorties qui n'est pas coché par le système de type, il n'y a pas grand-chose à prouver. –

-18

Les monades ne sont simplement pas importantes pour les programmeurs .NET. Sans même savoir que les monades existent, vous pouvez toujours créer le framework LINQ. Plus important encore, il ne semblerait pas différent. Peu importe si vous pensez en termes de monades (Haskell), de réécriture d'arbre d'expression (Lisp), d'opérations basées sur des ensembles (SQL), ou en utilisant map/reduce pour créer de nouveaux types (Ruby, Python), le résultat final est ça va être pareil. En fait, j'irais même jusqu'à dire que les monades sont carrément inutiles pour les développeurs .NET. Chaque fois que je vois une bibliothèque pour .NET basée sur des monades, elle est invariablement à la fois plus verbeuse et moins compréhensible que le code C# ou VB. La raison est simple, les langages comme C# et VB sont construits sur des blocs de construction beaucoup plus puissants que des langages comme Haskell.

Haskell en particulier a besoin d'utiliser des monades pour tout, parce que c'est tout ce qu'il possède. Il en va de même pour les macros en Lisp ou en typage dynamique en JavaScript. Quand vous avez un poney d'un tour, ce tour doit être sacrément bon.

On LINQ, Monads, and the Blindness of Power

+15

_ "La raison est simple, les langages comme C# et VB sont construits sur des blocs de construction beaucoup plus puissants que les langages comme Haskell." _ Dire que vous n'avez jamais programmé dans Haskell ou appris entièrement ses concepts. –

+2

Mérite des downvotes, si seulement pour inclure un lien vers "blog privé". –

+1

Cela ne mérite pas d'être downvoted. La question exige une vue opiniâtre de toute façon. Il a donné des raisons valables _against_ monades en C#. – usr