Mikan
Safe HaskellNone
LanguageHaskell2010

Mikan.Utils.ExpandCase

Description

This module is intended for high-performance programming. Concretely, the ExpandCase class can be used to force GHC to avoid compiling Reader, Endo or State-based code to unnecessary closures. You can observe its usage in Mikan.TypeChecking.Free.Generic. For a smaller example and some explanation, consider the following.

f :: Bool -> Endo Int
f b = case b of
  True  -> mempty
  False -> Endo (+ 10)

The desired -O1 output should be the following (ignoring newtype casts):

f = \b n -> case b of
  True  -> n
  False -> n + 10

A typical undesired output would be

f = \b -> case b of
  True  -> \n -> n
  False -> \n -> n + 10

Returning closures can be better or worse, depending on the program context. However, in high-performance situations we almost never want to return closures, and GHC is not nearly reliable enough at getting rid of the closures.

Using ExpandCase, we can write code as follows.

f :: Bool -> Endo Int
f b = expand \ret -> case b of
  True  -> ret mempty
  False -> ret $ Endo (+10)

Here, expand immediately introduces a lambda abstraction, and the ret continuation applies the "body" of the definition to the freshly abstracted variable. Hence, we get something like the following as an intermediate piece of Core:

f :: Bool -> Endo Int
f b = Endo \n -> case b of
  True  -> appEndo mempty n
  False -> appEndo (Endo (+10)) n

which is then reliably optimized to

f :: Bool -> Endo Int
f b = Endo \n -> case b of
  True  -> n
  False -> n + 10

NOTE: if you want to use this module, it is very strongly recommended that you check the Core of your code!

Synopsis

Documentation

class ExpandCase (rep :: RuntimeRep) a | a -> rep where Source #

Associated Types

type Result (rep :: RuntimeRep) a :: TYPE rep Source #

Methods

expand :: ((a -> Result rep a) -> Result rep a) -> a Source #

Instances

Instances details
ExpandCase LiftedRep All Source # 
Instance details

Defined in Mikan.Utils.ExpandCase

Associated Types

type Result LiftedRep All 
Instance details

Defined in Mikan.Utils.ExpandCase

ExpandCase LiftedRep Any Source # 
Instance details

Defined in Mikan.Utils.ExpandCase

Associated Types

type Result LiftedRep Any 
Instance details

Defined in Mikan.Utils.ExpandCase

ExpandCase LiftedRep () Source # 
Instance details

Defined in Mikan.Utils.ExpandCase

Associated Types

type Result LiftedRep () 
Instance details

Defined in Mikan.Utils.ExpandCase

Methods

expand :: ((() -> Result LiftedRep ()) -> Result LiftedRep ()) -> () Source #

ExpandCase LiftedRep Bool Source # 
Instance details

Defined in Mikan.Utils.ExpandCase

Associated Types

type Result LiftedRep Bool 
Instance details

Defined in Mikan.Utils.ExpandCase

ExpandCase LiftedRep Int Source # 
Instance details

Defined in Mikan.Utils.ExpandCase

Associated Types

type Result LiftedRep Int 
Instance details

Defined in Mikan.Utils.ExpandCase

ExpandCase LiftedRep (Tele a) Source # 
Instance details

Defined in Mikan.Syntax.Internal.Telescope

Associated Types

type Result LiftedRep (Tele a) 
Instance details

Defined in Mikan.Syntax.Internal.Telescope

Methods

expand :: ((Tele a -> Result LiftedRep (Tele a)) -> Result LiftedRep (Tele a)) -> Tele a Source #

ExpandCase LiftedRep (TCM a) Source # 
Instance details

Defined in Mikan.TypeChecking.Monad.Base

Associated Types

type Result LiftedRep (TCM a) 
Instance details

Defined in Mikan.TypeChecking.Monad.Base

type Result LiftedRep (TCM a) = IO a

Methods

expand :: ((TCM a -> Result LiftedRep (TCM a)) -> Result LiftedRep (TCM a)) -> TCM a Source #

ExpandCase LiftedRep (DontExpand a) Source # 
Instance details

Defined in Mikan.Utils.ExpandCase

Associated Types

type Result LiftedRep (DontExpand a) 
Instance details

Defined in Mikan.Utils.ExpandCase

ExpandCase LiftedRep (Endo a) Source # 
Instance details

Defined in Mikan.Utils.StrictEndo

Associated Types

type Result LiftedRep (Endo a) 
Instance details

Defined in Mikan.Utils.StrictEndo

type Result LiftedRep (Endo a) = a

Methods

expand :: ((Endo a -> Result LiftedRep (Endo a)) -> Result LiftedRep (Endo a)) -> Endo a Source #

ExpandCase LiftedRep (Endo a) Source # 
Instance details

Defined in Mikan.Utils.StrictFlipEndo

Associated Types

type Result LiftedRep (Endo a) 
Instance details

Defined in Mikan.Utils.StrictFlipEndo

type Result LiftedRep (Endo a) = a

Methods

expand :: ((Endo a -> Result LiftedRep (Endo a)) -> Result LiftedRep (Endo a)) -> Endo a Source #

ExpandCase LiftedRep (Endo a) Source # 
Instance details

Defined in Mikan.Utils.ExpandCase

Associated Types

type Result LiftedRep (Endo a) 
Instance details

Defined in Mikan.Utils.ExpandCase

type Result LiftedRep (Endo a) = a

Methods

expand :: ((Endo a -> Result LiftedRep (Endo a)) -> Result LiftedRep (Endo a)) -> Endo a Source #

ExpandCase LiftedRep (IO a) Source # 
Instance details

Defined in Mikan.Utils.ExpandCase

Associated Types

type Result LiftedRep (IO a) 
Instance details

Defined in Mikan.Utils.ExpandCase

Methods

expand :: ((IO a -> Result LiftedRep (IO a)) -> Result LiftedRep (IO a)) -> IO a Source #

ExpandCase LiftedRep (Maybe a) Source # 
Instance details

Defined in Mikan.Utils.ExpandCase

Associated Types

type Result LiftedRep (Maybe a) 
Instance details

Defined in Mikan.Utils.ExpandCase

Methods

expand :: ((Maybe a -> Result LiftedRep (Maybe a)) -> Result LiftedRep (Maybe a)) -> Maybe a Source #

ExpandCase LiftedRep [a] Source # 
Instance details

Defined in Mikan.Utils.ExpandCase

Associated Types

type Result LiftedRep [a] 
Instance details

Defined in Mikan.Utils.ExpandCase

Methods

expand :: (([a] -> Result LiftedRep [a]) -> Result LiftedRep [a]) -> [a] Source #

ExpandCase rep a => ExpandCase rep (ReduceM a) Source # 
Instance details

Defined in Mikan.TypeChecking.Monad.Base

Associated Types

type Result rep (ReduceM a) 
Instance details

Defined in Mikan.TypeChecking.Monad.Base

type Result rep (ReduceM a) = Result rep a

Methods

expand :: ((ReduceM a -> Result rep (ReduceM a)) -> Result rep (ReduceM a)) -> ReduceM a Source #

ExpandCase LiftedRep (Pair a b) Source # 
Instance details

Defined in Mikan.Utils.ExpandCase

Associated Types

type Result LiftedRep (Pair a b) 
Instance details

Defined in Mikan.Utils.ExpandCase

Methods

expand :: ((Pair a b -> Result LiftedRep (Pair a b)) -> Result LiftedRep (Pair a b)) -> Pair a b Source #

ExpandCase rep a => ExpandCase rep (Reader r a) Source # 
Instance details

Defined in Mikan.Utils.StrictReader

Associated Types

type Result rep (Reader r a) 
Instance details

Defined in Mikan.Utils.StrictReader

type Result rep (Reader r a) = Result rep a

Methods

expand :: ((Reader r a -> Result rep (Reader r a)) -> Result rep (Reader r a)) -> Reader r a Source #

ExpandCase rep (State w a) => ExpandCase rep (Writer w a) Source # 
Instance details

Defined in Mikan.Utils.StrictWriter

Associated Types

type Result rep (Writer w a) 
Instance details

Defined in Mikan.Utils.StrictWriter

type Result rep (Writer w a) = Result rep (State w a)

Methods

expand :: ((Writer w a -> Result rep (Writer w a)) -> Result rep (Writer w a)) -> Writer w a Source #

ExpandCase rep (m a) => ExpandCase rep (ReaderT r m a) Source # 
Instance details

Defined in Mikan.Utils.StrictReader

Associated Types

type Result rep (ReaderT r m a) 
Instance details

Defined in Mikan.Utils.StrictReader

type Result rep (ReaderT r m a) = Result rep (m a)

Methods

expand :: ((ReaderT r m a -> Result rep (ReaderT r m a)) -> Result rep (ReaderT r m a)) -> ReaderT r m a Source #

ExpandCase rep (m (Pair a s)) => ExpandCase rep (StateT s m a) Source # 
Instance details

Defined in Mikan.Utils.StrictState

Associated Types

type Result rep (StateT s m a) 
Instance details

Defined in Mikan.Utils.StrictState

type Result rep (StateT s m a) = Result rep (m (Pair a s))

Methods

expand :: ((StateT s m a -> Result rep (StateT s m a)) -> Result rep (StateT s m a)) -> StateT s m a Source #

ExpandCase rep (m (Pair a w)) => ExpandCase rep (WriterT w m a) Source # 
Instance details

Defined in Mikan.Utils.StrictWriter

Associated Types

type Result rep (WriterT w m a) 
Instance details

Defined in Mikan.Utils.StrictWriter

type Result rep (WriterT w m a) = Result rep (StateT w m a)

Methods

expand :: ((WriterT w m a -> Result rep (WriterT w m a)) -> Result rep (WriterT w m a)) -> WriterT w m a Source #

ExpandCase ('TupleRep '[LiftedRep, LiftedRep]) (State s a) Source # 
Instance details

Defined in Mikan.Utils.StrictState

Associated Types

type Result ('TupleRep '[LiftedRep, LiftedRep]) (State s a) 
Instance details

Defined in Mikan.Utils.StrictState

type Result ('TupleRep '[LiftedRep, LiftedRep]) (State s a) = (# a, s #)

Methods

expand :: ((State s a -> Result ('TupleRep '[LiftedRep, LiftedRep]) (State s a)) -> Result ('TupleRep '[LiftedRep, LiftedRep]) (State s a)) -> State s a Source #

Deriving helpers

newtype DontExpand a Source #

Constructors

DontExpand 

Fields

Instances

Instances details
ExpandCase LiftedRep (DontExpand a) Source # 
Instance details

Defined in Mikan.Utils.ExpandCase

Associated Types

type Result LiftedRep (DontExpand a) 
Instance details

Defined in Mikan.Utils.ExpandCase

type Result LiftedRep (DontExpand a) Source # 
Instance details

Defined in Mikan.Utils.ExpandCase

Re-exports

type LiftedRep = 'BoxedRep 'Lifted #

The runtime representation of lifted types.