5 votes

Puis-je passer un dictionnaire de classe de type à une fonction de manière explicite ?

Disons que j'ai une classe de type :

data Foo = Foo deriving (Show)

class Monad m => MonadFoo m where
  getFoo :: m Foo

Puisque GHC implémente les classes de type via le passage par dictionnaire (utilisations de SPECIALIZE nonobstant), elle transforme effectivement getFoo en quelque chose comme ce qui suit sous le capot :

data MonadFooDict m = MonadFooDict { getFoo :: m Foo }

...et il insère un argument supplémentaire au début des appels à getFoo qui fait tourner le dictionnaire.

Parfois, je peux vouloir choisir une instance de manière dynamique, et il peut être souhaitable de passer moi-même un dictionnaire. Je peux simuler cela moi-même en créant une instance qui transmettra le dictionnaire à ma place.

newtype DynamicMonadFoo a = DynamicMonadFoo
    { runFoo :: MonadFooDict DynamicMonadFoo -> a }
  deriving ( Functor, Applicative, Monad
           , MonadReader (MonadFooDict DynamicMonadFoo) )

instance MonadFoo DynamicMonadFoo where
  getFoo = join $ asks _getFoo

Maintenant, étant donné une fonction avec un MonadFoo je peux utiliser la contrainte runFoo pour lui passer un dictionnaire de classes de types explicite :

showCurrentFoo :: MonadFoo m => m String
showCurrentFoo = do
  foo <- getFoo
  return ("current foo: " ++ show foo)

ghci> runFoo showCurrentFoo MonadFooDict { _getFoo = return Foo }
"current foo: Foo"

C'est vraiment cool, mais cela semble être une tâche si simple que GHC pourrait exposer une sorte de bibliothèque pour faire cela sans tout le boilerplate (et idéalement d'une manière qui fonctionnerait mieux avec les classes de type non monadiques). Étant donné que GHC dispose de certaines capacités "semblables à la réflexion", telles que Data.Typeable Je ne pense pas que cela soit hors du domaine du possible, mais je ne suis pas sûr que cela existe réellement sous une forme ou une autre.

Existe-t-il des modules intégrés ou d'autres bibliothèques qui permettent de faire cela de manière plus automatique ?

5voto

user5402 Points 8479

Il existe un article sur ce sujet à l'école de Haskell :

Refléter les valeurs aux types et inversement

Voir la section vers la fin intitulée Construire dynamiquement des instances de classe de type y Mais qu'en est-il des dictionnaires manuels ?

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X