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.
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 –