module Fx.Executor ( Executor(..), mapEffect, mapContext, execute, ) where import Fx.Prelude {-| An abstraction over the execution of @effect@ in @context@, both producing the same @result@. -} newtype Executor effect context = Executor (forall result. effect result -> context result) {-| Use the executor to run an effect in a context. -} execute :: Executor effect context -> effect result -> context result execute (Executor def) effect = def effect {-| Map the effect part of an executor (contravariantly). -} mapEffect :: (forall result. newEffect result -> oldEffect result) -> Executor oldEffect context -> Executor newEffect context mapEffect mapping (Executor fn) = Executor (fn . mapping) {-| Map the context part of an executor. -} mapContext :: (forall result. oldContext result -> newContext result) -> Executor effect oldContext -> Executor effect newContext mapContext mapping (Executor fn) = Executor (mapping . fn)