module Control.Monad.Hyper
( ContravariantFunctor(..)
, Hyper
, Hyp
, HyperB(..)
) where
import Control.Bifunctor.Fix
import Control.Monad.Parameterized
import Control.Functor.Contravariant
import Control.Monad.Instances
newtype HyperB h a b = HyperB { runHyperB :: h b -> a }
instance ContravariantFunctor h => Bifunctor (HyperB h) where
bimap f g h = HyperB (f . runHyperB h . contramap g)
instance ContravariantFunctor h => PPointed (HyperB h) where
preturn = HyperB . const
instance ContravariantFunctor h => PApplicative (HyperB h) where
pap = papPMonad
instance ContravariantFunctor h => PMonad (HyperB h) where
pbind k (HyperB h) = HyperB (k . h >>= runHyperB)
type Hyper h a = FixB (HyperB h)
type Hyp e a = Hyper (ContraF e) a