<div dir="ltr"><div>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)</div><div> <br></div><div>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. <br></div><div><br></div><div>It isn't hard when number of options is low. I suppose, we can use something like</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div>typeclass Context a where<br></div><div>{  dispatch :: MonadIO m => forall k . Context a -> (forall a . Testable1 a -> a -> m k) -> (forall a. Testable2 a -> a -> m k ) -> a -> m k }<br></div></blockquote><div><br></div><div>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.</div><div><br></div><div>The problems are twofold:</div><div>- This is not extensible, the set of possible cases is defined on the definition of Context  typeclass</div><div>- 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 <i>dispatch</i> needs to support<br></div><div><br></div><div>A more modular approach is needed, something like (pseudocode)<br></div><div><br></div><div>dispatch :: <br></div><div>  typeclassSet Defined,  -- collection of defined typeclasses<br></div><div>  typeClass Tested, -- what we test for</div><div>  Dispatchable a, Defined a -- what we test<br></div><div>  =>forall b. <br></div><div>   (forall a . Defined a => a -> b) -- 'fallback' function</div><div>   -> (forall a . Defined a, Tested a => a -> b) -- this is called if A supports Tested interface.</div><div>   -> b</div><div><br></div><div><br></div><div>This way one can gradually inject typeclass instances into scope. But how I can do it? <br></div><div><br></div><div>PS. Naturally, I don't want to expose internals of the type I dispatch over, it is an abstract type.<br></div><div><div><br></div></div></div>