-- | -- Module: Control.Wire.Classes -- Copyright: (c) 2011 Ertugrul Soeylemez -- License: BSD3 -- Maintainer: Ertugrul Soeylemez -- -- Type classes used in Netwire. module Control.Wire.Classes ( -- * Various effects -- ** Time MonadClock(..), -- ** Underlying monad ArrowKleisli(..), arrIO ) where import Control.Applicative import Control.Arrow import Control.Arrow.Transformer import Control.Arrow.Transformer.Automaton import Control.Arrow.Transformer.Error import Control.Arrow.Transformer.Reader import Control.Arrow.Transformer.State import Control.Arrow.Transformer.Static import Control.Arrow.Transformer.Writer import Control.Monad.Trans (MonadIO(..)) import Data.Monoid import Data.Time.Clock.POSIX -- | Monads with a clock. class Monad m => MonadClock t m | m -> t where -- | Current time in some monad-specific frame of reference. getTime :: m t -- | Instance for the system time. This is intentionally specific to -- allow you to define better instances with custom monads. instance MonadClock Double IO where getTime = fmap realToFrac getPOSIXTime -- | Arrows which support running monadic computations. class Arrow (>~) => ArrowKleisli m (>~) | (>~) -> m where -- | Run the input computation and output its result. arrM :: Monad m => m b >~ b instance Monad m => ArrowKleisli m (Kleisli m) where arrM = Kleisli id instance ArrowKleisli m (>~) => ArrowKleisli m (Automaton (>~)) where arrM = lift arrM instance (ArrowChoice (>~), ArrowKleisli m (>~)) => ArrowKleisli m (ErrorArrow ex (>~)) where arrM = lift arrM instance ArrowKleisli m (>~) => ArrowKleisli m (ReaderArrow e (>~)) where arrM = lift arrM instance ArrowKleisli m (>~) => ArrowKleisli m (StateArrow s (>~)) where arrM = lift arrM instance (Applicative f, ArrowKleisli m (>~)) => ArrowKleisli m (StaticArrow f (>~)) where arrM = lift arrM instance (ArrowKleisli m (>~), Monoid l) => ArrowKleisli m (WriterArrow l (>~)) where arrM = lift arrM -- | Arrows, which have 'IO' at their base. arrIO :: (ArrowKleisli m (>~), MonadIO m) => IO b >~ b arrIO = arrM <<^ liftIO