summaryrefslogtreecommitdiff
path: root/compiler/GHC/Data/Unboxed.hs
blob: dbd197351bd49b417e43d83647000ffbdd0494c0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
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