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?