Can I skip the dictionary with the software for the function explicitly?

Suppose I have several types:

data Foo = Foo deriving (Show) class Monad m => MonadFoo m where getFoo :: m Foo 

Since GHC implements type classes through word passing (despite using SPECIALIZE ), it effectively converts getFoo into something like the following under the hood:

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

... and he inserts an extra argument at the start of the getFoo calls that surrounds the dictionary.

Sometimes I may want to select the instance dynamically, so going through the dictionary itself may be desirable. I can simulate this on my own by creating an instance that will change the dictionary for me.

 newtype DynamicMonadFoo a = DynamicMonadFoo { runFoo :: MonadFooDict DynamicMonadFoo -> a } deriving ( Functor, Applicative, Monad , MonadReader (MonadFooDict DynamicMonadFoo) ) instance MonadFoo DynamicMonadFoo where getFoo = join $ asks _getFoo 

Now, given some function with a MonadFoo constraint, I can use the runFoo function to pass it an explicit style dictionary:

 showCurrentFoo :: MonadFoo m => m String showCurrentFoo = do foo <- getFoo return ("current foo: " ++ show foo) ghci> runFoo showCurrentFoo MonadFooDict { _getFoo = return Foo } "current foo: Foo" 

It's really cool, but it seems like such a simple task that the GHC can set up some kind of library for this without any template (and ideally, this will work better with non-monodic classes). Given that the GHC has some β€œreflective capabilities,” such as Data.Typeable , this does not seem to be beyond the scope, but Im not sure if it really exists in one form or another.

Are any existing built-in or other libraries allowed?

+5
source share
1 answer

All Articles