-- Unboxed counterparts to data structures {-# LANGUAGE UnboxedTuples #-} {-# LANGUAGE PatternSynonyms #-} {-# LANGUAGE UnliftedNewtypes #-} module GHC.Data.Unboxed ( MaybeUB(JustUB, NothingUB), fmapMaybeUB, fromMaybeUB, apMaybeUB, maybeUB ) where import GHC.Prelude hiding (Maybe(..), Either(..)) -- | Like Maybe, but using unboxed sums. -- -- Use with care. Using a unboxed maybe is not always a win -- in execution *time* even when allocations go down. So make -- sure to benchmark for execution time as well. If the difference -- in *runtime* for the compiler is too small to measure it's likely -- better to use a regular Maybe instead. -- -- This is since it causes more function arguments to be passed, and -- potentially more variables to be captured by closures increasing -- closure size. newtype MaybeUB a = MaybeUB (# (# #) | a #) pattern JustUB :: a -> MaybeUB a pattern JustUB x = MaybeUB (# | x #) pattern NothingUB :: MaybeUB a pattern NothingUB = MaybeUB (# (# #) | #) {-# COMPLETE NothingUB, JustUB #-} fromMaybeUB :: a -> MaybeUB a -> a fromMaybeUB d NothingUB = d fromMaybeUB _ (JustUB x) = x apMaybeUB :: MaybeUB (a -> b) -> MaybeUB a -> MaybeUB b apMaybeUB (JustUB f) (JustUB x) = JustUB (f x) apMaybeUB _ _ = NothingUB fmapMaybeUB :: (a -> b) -> MaybeUB a -> MaybeUB b fmapMaybeUB _f NothingUB = NothingUB fmapMaybeUB f (JustUB x) = JustUB $ f x maybeUB :: b -> (a -> b) -> MaybeUB a -> b maybeUB _def f (JustUB x) = f x maybeUB def _f NothingUB = def