<div dir="ltr">Hi,<div><br></div><div>I'm trying to develop a GHC plugin to transform effect handlers for free monads. I have created my own module with the free monad definitions. The goal is that if a user uses these definitions, my plugin will rewrite the handlers into a form which will allow fusion.</div><div><br></div><div><br></div><div>For a first simple example I'm trying to transform the following code:</div><div><br></div><div><div>handleNondet :: Functor g => Free (Nondet + g) a -> Free g [a]</div><div>handleNondet = \y -> case y of</div><div>    Var x -> Var [x]</div><div>    Con op -> case op of</div><div>        Inl x -> case x of</div><div>            Or l r -> (handleNondet l >>= (\ll -> handleNondet r >>= (\rr -> Var (ll ++ rr))))</div><div>        Inr x -> Con (fmap handleNondet x)</div></div><div><br></div><div><br></div><div>into this:</div><div><br></div><div><div>handleNondet :: Functor g => Free (Nondet + g) a -> Free g [a]</div><div>handleNondet = <span style="line-height:1.5">foldFree genNondet algNondet</span></div><div><br></div><div>genNondet :: Functor g => a -> Free g [a]</div><div>genNondet x = Var [x]</div><div><br></div><div>algNondet :: Functor g => (Nondet + g) (Free g [a]) -> Free g [a]</div><div>algNondet op = case op of</div><div>    Inl x -> case x of</div><div>        Or l r -> (l >>= (\ll -> r >>= (\rr -> Var (ll ++ rr))))</div><div>    Inr x -> Con x</div></div><div><br></div><div>-----------------------------------------------------------------------------------------------------------------------------------</div><div><br></div><div>In my module with definitions, Free, Con, Var, the (+), Inl and Inr are defined and the foldFree function is defined.</div><div>There is also a functor instance:    instance (Functor f, Functor g) => Functor (f + g)</div><div><br></div><div><br></div><div>The problem is that when trying to do this transformation in GHC Core, I only get a dictionary for the functor g, but not for Nondet or for (Nondet + g).</div><div>What is need is of the form: </div><div>(WhatMorphism.Free.$fFunctor+</div><div>                @ Nondet @ g_a2MS Types.$fFunctorNondet $dFunctor_a2R9)</div><div><br></div><div>and I have access to @ Nondet, @ g_a2MS and $dFunctor_a2R9, but I don't know how to find WhatMorphism.Free.$fFunctor+ and Types.$fFunctorNondet.</div><div><br></div><div>I am trying to find out whether it is possible to find these dictionaries from a GHC Core plugin, or whether this has to happen in an earlier stage of the compilation. If it is possible, how would I go about it? And if it is not, where should I start looking to implement this functionality anyway?</div><div><br></div><div>Regards,</div><div>Yannick Boesmans</div></div>