[Haskell-cafe] Dispatching user code at runtime, injecting appropriate typeclass instances into user code scope

Evgeny Permyakov permeakra at gmail.com
Thu May 16 07:02:28 UTC 2019

Let's suppose that at runtime I create a hardware context and test it for a
set of supported operation and want to adapt the way I work with it based
on the set of operations available. (RL example: OpenGL extension discovery
and use)

Naturally, I can create a function that checks hardware and then, based on
the result, returns different dictionaries of functions over the context,
maybe as closures. This is verbose and crude, even if it shall work.
However, I want to work with the context using a typeclass interface.

It isn't hard when number of options is low. I suppose, we can use
something like

typeclass Context a where
> {  dispatch :: MonadIO m => forall k . Context a -> (forall a . Testable1
> a -> a -> m k) -> (forall a. Testable2 a -> a -> m k ) -> a -> m k }

Here, Context typeclass  defines a function that selects appropriate
handler from the set of user-provided functions and each instance takes the
function it likes. Fine.

The problems are twofold:
- This is not extensible, the set of possible cases is defined on the
definition of Context  typeclass
- This approach is hardly appropriate if we have  a lot of cases, For
example, if context may support ten optional operation sets in addtion to
basic one, the number of possible cases *dispatch* needs to support

A more modular approach is needed, something like (pseudocode)

dispatch ::
  typeclassSet Defined,  -- collection of defined typeclasses
  typeClass Tested, -- what we test for
  Dispatchable a, Defined a -- what we test
  =>forall b.
   (forall a . Defined a => a -> b) -- 'fallback' function
   -> (forall a . Defined a, Tested a => a -> b) -- this is called if A
supports Tested interface.
   -> b

This way one can gradually inject typeclass instances into scope. But how I
can do it?

PS. Naturally, I don't want to expose internals of the type I dispatch
over, it is an abstract type.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/haskell-cafe/attachments/20190516/9da9867b/attachment.html>

More information about the Haskell-Cafe mailing list