{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE InstanceSigs #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE MultiParamTypeClasses #-}
module Control.FX.Monad.WriteOnly (
WriteOnly(..)
, Context(..)
, Input(..)
, Output(..)
) where
import Data.Typeable (Typeable)
import Control.FX.EqIn
import Control.FX.Functor
import Control.FX.Monad.Class
newtype WriteOnly
(mark :: * -> *)
(w :: *)
(a :: *)
= WriteOnly
{ unWriteOnly :: Pair w a
} deriving (Eq, Show, Typeable)
instance
( Monoid w, MonadIdentity mark
) => Functor (WriteOnly mark w)
where
fmap
:: (a -> b)
-> WriteOnly mark w a
-> WriteOnly mark w b
fmap f = WriteOnly . fmap f . unWriteOnly
instance
( Monoid w, MonadIdentity mark
) => Applicative (WriteOnly mark w)
where
pure
:: a
-> WriteOnly mark w a
pure = WriteOnly . Pair mempty
(<*>)
:: WriteOnly mark w (a -> b)
-> WriteOnly mark w a
-> WriteOnly mark w b
(WriteOnly (Pair w1 f)) <*> (WriteOnly (Pair w2 x)) =
WriteOnly (Pair (w1 <> w2) (f x))
instance
( Monoid w, MonadIdentity mark
) => Monad (WriteOnly mark w)
where
return
:: a
-> WriteOnly mark w a
return = WriteOnly . Pair mempty
(>>=)
:: WriteOnly mark w a
-> (a -> WriteOnly mark w b)
-> WriteOnly mark w b
(WriteOnly (Pair w1 x)) >>= f =
let Pair w2 y = unWriteOnly $ f x in
WriteOnly $ Pair (w1 <> w2) y
instance
( Monoid w, MonadIdentity mark
) => Commutant (WriteOnly mark w)
where
commute
:: ( Applicative f )
=> WriteOnly mark w (f a)
-> f (WriteOnly mark w a)
commute (WriteOnly (Pair w x)) =
fmap (\a -> (WriteOnly (Pair w a))) x
instance
( MonadIdentity mark
) => Bifunctor (WriteOnly mark)
where
bimap1
:: (w -> v)
-> WriteOnly mark w a
-> WriteOnly mark v a
bimap1 f = WriteOnly . bimap1 f . unWriteOnly
bimap2
:: (a -> b)
-> WriteOnly mark w a
-> WriteOnly mark w b
bimap2 f = WriteOnly . bimap2 f . unWriteOnly
instance
( Monoid w, MonadIdentity mark
) => Central (WriteOnly mark w)
instance
( Eq w
) => EqIn (WriteOnly mark w)
where
newtype Context (WriteOnly mark w)
= WriteOnlyCtx
{ unWriteOnlyCtx :: mark ()
} deriving (Typeable)
eqIn
:: (Eq a)
=> Context (WriteOnly mark w)
-> WriteOnly mark w a
-> WriteOnly mark w a
-> Bool
eqIn _ = (==)
deriving instance
( Eq (mark ())
) => Eq (Context (WriteOnly mark w))
deriving instance
( Show (mark ())
) => Show (Context (WriteOnly mark w))
instance
( Monoid w, MonadIdentity mark
) => RunMonad (WriteOnly mark w)
where
newtype Input (WriteOnly mark w)
= WriteOnlyIn
{ unWriteOnlyIn :: mark ()
} deriving (Typeable)
newtype Output (WriteOnly mark w) a
= WriteOnlyOut
{ unWriteOnlyOut :: Pair (mark w) a
} deriving (Typeable)
run
:: Input (WriteOnly mark w)
-> WriteOnly mark w a
-> Output (WriteOnly mark w) a
run _ (WriteOnly (Pair w a)) =
WriteOnlyOut $ Pair (pure w) a
deriving instance
( Eq (mark ())
) => Eq (Input (WriteOnly mark w))
deriving instance
( Show (mark ())
) => Show (Input (WriteOnly mark w))
deriving instance
( Eq (mark w), Eq a
) => Eq (Output (WriteOnly mark w) a)
deriving instance
( Show (mark w), Show a
) => Show (Output (WriteOnly mark w) a)
instance
( Monoid w, MonadIdentity mark
) => MonadWriteOnly mark w (WriteOnly mark w)
where
tell
:: mark w
-> WriteOnly mark w ()
tell w =
WriteOnly (Pair (unwrap w) ())
draft
:: WriteOnly mark w a
-> WriteOnly mark w (Pair (mark w) a)
draft (WriteOnly (Pair w a)) =
WriteOnly (Pair mempty (Pair (pure w) a))