{-|
Module: Reflex.Class.Switchable
Description: A class for things that can be switched on the firing of an event
-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE UndecidableInstances #-}
module Reflex.Class.Switchable where

import Control.Monad
import Reflex

-- | Class representing things that can be switched when the provided event occurs
class Reflex t => Switchable t w | w -> t where
  switching :: MonadHold t m => w -> Event t w -> m w

instance Reflex t => Switchable t (Event t a) where
  switching :: Event t a -> Event t (Event t a) -> m (Event t a)
switching = Event t a -> Event t (Event t a) -> m (Event t a)
forall k (t :: k) (m :: * -> *) a.
(Reflex t, MonadHold t m) =>
Event t a -> Event t (Event t a) -> m (Event t a)
switchHold

instance Reflex t => Switchable t (Dynamic t a) where
  switching :: Dynamic t a -> Event t (Dynamic t a) -> m (Dynamic t a)
switching a :: Dynamic t a
a e :: Event t (Dynamic t a)
e = (Dynamic t (Dynamic t a) -> Dynamic t a)
-> m (Dynamic t (Dynamic t a)) -> m (Dynamic t a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Dynamic t (Dynamic t a) -> Dynamic t a
forall (m :: * -> *) a. Monad m => m (m a) -> m a
join (m (Dynamic t (Dynamic t a)) -> m (Dynamic t a))
-> m (Dynamic t (Dynamic t a)) -> m (Dynamic t a)
forall a b. (a -> b) -> a -> b
$ Dynamic t a -> Event t (Dynamic t a) -> m (Dynamic t (Dynamic t a))
forall k (t :: k) (m :: * -> *) a.
MonadHold t m =>
a -> Event t a -> m (Dynamic t a)
holdDyn Dynamic t a
a Event t (Dynamic t a)
e

instance Reflex t => Switchable t (Behavior t a) where
  switching :: Behavior t a -> Event t (Behavior t a) -> m (Behavior t a)
switching = Behavior t a -> Event t (Behavior t a) -> m (Behavior t a)
forall k (t :: k) (m :: * -> *) a.
(Reflex t, MonadHold t m) =>
Behavior t a -> Event t (Behavior t a) -> m (Behavior t a)
switcher

instance (Reflex t, Switchable t a, Switchable t b) => Switchable t (a, b) where
  switching :: (a, b) -> Event t (a, b) -> m (a, b)
switching (a :: a
a, b :: b
b) e :: Event t (a, b)
e = (,)
    (a -> b -> (a, b)) -> m a -> m (b -> (a, b))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> a -> Event t a -> m a
forall t w (m :: * -> *).
(Switchable t w, MonadHold t m) =>
w -> Event t w -> m w
switching a
a (((a, b) -> a) -> Event t (a, b) -> Event t a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (a, b) -> a
forall a b. (a, b) -> a
fst Event t (a, b)
e)
    m (b -> (a, b)) -> m b -> m (a, b)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> b -> Event t b -> m b
forall t w (m :: * -> *).
(Switchable t w, MonadHold t m) =>
w -> Event t w -> m w
switching b
b (((a, b) -> b) -> Event t (a, b) -> Event t b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (a, b) -> b
forall a b. (a, b) -> b
snd Event t (a, b)
e)