Search code examples
haskellfunctional-programminghaskell-polysemyeffect-systems

How to modify the type of a Reader effect in Haskell Polysemy?


The Reader effect provides a local method which modifies the value to be read within a local scope:

local :: Member (Reader i) r => (i -> i) -> Sem r a -> Sem r a

The function passed to local must not change the type of the data. I would like to be able to avoid this restriction, and have an alternative to local which can modify the type of the reader value.

The obvious way to implement this is with an interpreter-style function like this:

local' :: (i -> j) -> Sem (Reader j ': r) a -> Sem (Reader i ': r) a

The problem with this approach is that it requires that the Reader effect is on the top of the effect stack, which may not be the case.

How can I solve this problem and modify the effect anywhere in the effect stack? If a concrete effect stack can be re-ordered, then this would also solve the problem when used in conjunction with local', but I cannot find any functions to do this either.


Solution

  • As mentioned in the comments, using the following type signature doesn't require the effects to be in a fixed order:

    local' :: Member (Reader a) r => (a -> b) -> InterpreterFor (Reader b) r