{-# LANGUAGE DerivingVia #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE UnboxedTuples #-}
{-# LANGUAGE UndecidableInstances #-}
module Mikan.Utils.ExpandCase
( ExpandCase(..)
, DontExpand(..)
, LiftedRep
)
where
import Data.Monoid
import GHC.Exts (oneShot, RuntimeRep(..), TYPE, LiftedRep)
import Data.Strict.Tuple
class ExpandCase rep a | a -> rep where
type Result rep a :: TYPE rep
expand :: ((a -> Result rep a) -> Result rep a) -> a
newtype DontExpand a = DontExpand { forall a. DontExpand a -> a
unDontExpand :: a }
instance ExpandCase LiftedRep (DontExpand a) where
type Result LiftedRep (DontExpand a) = a
{-# INLINE expand #-}
expand :: ((DontExpand a -> Result LiftedRep (DontExpand a))
-> Result LiftedRep (DontExpand a))
-> DontExpand a
expand (DontExpand a -> Result LiftedRep (DontExpand a))
-> Result LiftedRep (DontExpand a)
k = a -> DontExpand a
forall a. a -> DontExpand a
DontExpand ((DontExpand a -> Result LiftedRep (DontExpand a))
-> Result LiftedRep (DontExpand a)
k DontExpand a -> a
DontExpand a -> Result LiftedRep (DontExpand a)
forall a. DontExpand a -> a
unDontExpand)
deriving via DontExpand Any instance ExpandCase LiftedRep Any
deriving via DontExpand All instance ExpandCase LiftedRep All
deriving via DontExpand Bool instance ExpandCase LiftedRep Bool
deriving via DontExpand Int instance ExpandCase LiftedRep Int
deriving via DontExpand () instance ExpandCase LiftedRep ()
deriving via DontExpand (Pair a b) instance ExpandCase LiftedRep (Pair a b)
deriving via DontExpand (IO a) instance ExpandCase LiftedRep (IO a)
deriving via DontExpand [a] instance ExpandCase LiftedRep [a]
deriving via DontExpand (Maybe a) instance ExpandCase LiftedRep (Maybe a)
instance ExpandCase LiftedRep (Endo a) where
type Result LiftedRep (Endo a) = a
{-# INLINE expand #-}
expand :: ((Endo a -> Result LiftedRep (Endo a))
-> Result LiftedRep (Endo a))
-> Endo a
expand (Endo a -> Result LiftedRep (Endo a)) -> Result LiftedRep (Endo a)
k = (a -> a) -> Endo a
forall a. (a -> a) -> Endo a
Endo ((a -> a) -> a -> a
forall a b. (a -> b) -> a -> b
oneShot \a
a -> (Endo a -> Result LiftedRep (Endo a)) -> Result LiftedRep (Endo a)
k ((Endo a -> a) -> Endo a -> a
forall a b. (a -> b) -> a -> b
oneShot \Endo a
act -> Endo a -> a -> a
forall a. Endo a -> a -> a
appEndo Endo a
act a
a))