{-# LANGUAGE CPP #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UndecidableInstances #-}
#ifdef USE_REFLEX_OPTIMIZER
{-# OPTIONS_GHC -fplugin=Reflex.Optimizer #-}
#endif
module Reflex.PerformEvent.Class
( PerformEvent (..)
, performEventAsync
) where
import Control.Monad.Reader
import Control.Monad.Trans.Maybe (MaybeT (..))
import Data.Kind (Type)
import Reflex.Class
import Reflex.TriggerEvent.Class
class (Reflex t, Monad (Performable m), Monad m) => PerformEvent t m | m -> t where
type Performable m :: Type -> Type
performEvent :: Event t (Performable m a) -> m (Event t a)
performEvent_ :: Event t (Performable m ()) -> m ()
{-# INLINABLE performEventAsync #-}
performEventAsync :: (TriggerEvent t m, PerformEvent t m) => Event t ((a -> IO ()) -> Performable m ()) -> m (Event t a)
performEventAsync e = do
(eOut, triggerEOut) <- newTriggerEvent
performEvent_ $ fmap ($ triggerEOut) e
return eOut
instance PerformEvent t m => PerformEvent t (ReaderT r m) where
type Performable (ReaderT r m) = ReaderT r (Performable m)
performEvent_ e = do
r <- ask
lift $ performEvent_ $ flip runReaderT r <$> e
performEvent e = do
r <- ask
lift $ performEvent $ flip runReaderT r <$> e
instance PerformEvent t m => PerformEvent t (MaybeT m) where
type Performable (MaybeT m) = MaybeT (Performable m)
performEvent_ = lift . performEvent_ . fmapCheap (void . runMaybeT)
performEvent = lift . fmap (fmapMaybe id) . performEvent . fmapCheap runMaybeT