summaryrefslogtreecommitdiff
path: root/compiler/GHC/Data/Unboxed.hs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/GHC/Data/Unboxed.hs')
-rw-r--r--compiler/GHC/Data/Unboxed.hs50
1 files changed, 50 insertions, 0 deletions
diff --git a/compiler/GHC/Data/Unboxed.hs b/compiler/GHC/Data/Unboxed.hs
new file mode 100644
index 0000000000..dbd197351b
--- /dev/null
+++ b/compiler/GHC/Data/Unboxed.hs
@@ -0,0 +1,50 @@
+-- Unboxed counterparts to data structures
+
+{-# LANGUAGE UnboxedSums #-}
+{-# 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