1 {-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, ConstraintKinds, TemplateHaskell, TypeSynonymInstances, LiberalTypeSynonyms #-} 2 module Databrary.Has 3 ( Has(..) 4 , MonadHas 5 , peek 6 , peeks 7 , focusIO 8 ) where 9 10 import Control.Monad.IO.Class (MonadIO(..)) 11 import Control.Monad.Reader (MonadReader, ReaderT(..), reader) 12 13 class Has a c where 14 view :: c -> a 15 16 instance Has a a where 17 view = id 18 19 type MonadHas a s m = (Functor m, Applicative m, MonadReader s m, Has a s) 20 21 {-# INLINE peek #-} 22 peek :: (MonadReader c m, Has a c) => m a 23 peek = reader view 24 25 {-# INLINE peeks #-} 26 peeks :: (MonadReader c m, Has a c) => (a -> b) -> m b 27 peeks f = reader (f . view) 28 29 {-# INLINE focusReader #-} 30 focusReader :: Has a c => (a -> m b) -> ReaderT c m b 31 focusReader f = ReaderT (f . view) 32 33 {-# INLINE[2] focusIO #-} 34 focusIO :: (MonadIO m, MonadHas a c m) => (a -> IO b) -> m b 35 focusIO f = liftIO . f =<< peek 36 37 {-# RULES "focusIO/ReaderT" focusIO = focusReader #-}