{-# LANGUAGE NamedFieldPuns #-} {-# LANGUAGE FunctionalDependencies #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE UndecidableInstances #-} module PDF.Box ( Box(..) , (.@) , edit , modifyAt ) where import Control.Monad.State (MonadState(..)) class Monad m => Box m i a b | m a i -> b where r :: i -> a -> m b w :: i -> a -> b -> m a edit :: Box m i a b => i -> (b -> m b) -> a -> m a edit i f a = r i a >>= f >>= w i a modifyAt :: (MonadState a m, Box m i a b) => i -> (b -> m b) -> m () modifyAt i f = get >>= edit i f >>= put instance (Box m i a b, Box m j b c) => Box m (i, j) a c where r (i, j) a = r i a >>= r j w (i, j) a c = r i a >>= flip (w j) c >>= w i a infixr 6 .@ (.@) :: a -> b -> (a, b) (.@) = (,)