{-# LANGUAGE MagicHash #-}
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE UnboxedSums #-}
{-# LANGUAGE UnboxedTuples #-}
{-# LANGUAGE ViewPatterns #-}

module Data.Maybe.Unpacked.Numeric.Int32
  ( Maybe (..)
  , just
  , nothing
  , maybe
  , isJust
  , isNothing
  , fromMaybe
  , listToMaybe
  , maybeToList
  , catMaybes
  , mapMaybe
  , toBaseMaybe
  , fromBaseMaybe
    -- * Patterns
  , pattern Nothing
  , pattern Just
  ) where

import Prelude hiding (Just, Maybe, Nothing, maybe)

import GHC.Exts
import GHC.Int (Int32)
import GHC.Int.Compat (pattern I32#)

import GHC.Read (Read (readPrec))
import Text.ParserCombinators.ReadPrec (prec, step)
import Text.Read (Lexeme (Ident), lexP, parens, (+++))

import qualified Prelude as P

data Maybe = M Int#

instance Eq Maybe where
  Maybe
ma == :: Maybe -> Maybe -> Bool
== Maybe
mb =
    Bool -> (Int32 -> Bool) -> Maybe -> Bool
forall a. a -> (Int32 -> a) -> Maybe -> a
maybe
      (Maybe -> Bool
isNothing Maybe
mb)
      (\Int32
a -> Bool -> (Int32 -> Bool) -> Maybe -> Bool
forall a. a -> (Int32 -> a) -> Maybe -> a
maybe Bool
False (\Int32
b -> Int32
a Int32 -> Int32 -> Bool
forall a. Eq a => a -> a -> Bool
== Int32
b) Maybe
mb)
      Maybe
ma
  {-# INLINE (==) #-}

instance Ord Maybe where
  compare :: Maybe -> Maybe -> Ordering
compare Maybe
ma Maybe
mb = case Maybe
ma of
    Just Int32
a -> case Maybe
mb of
      Just Int32
b -> Int32 -> Int32 -> Ordering
forall a. Ord a => a -> a -> Ordering
compare Int32
a Int32
b
      Maybe
_ -> Ordering
GT
    Maybe
_ -> case Maybe
mb of
      Just{} -> Ordering
LT
      Maybe
_ -> Ordering
EQ

instance Show Maybe where
  showsPrec :: Int -> Maybe -> ShowS
showsPrec Int
p Maybe
m =
    ShowS -> (Int32 -> ShowS) -> Maybe -> ShowS
forall a. a -> (Int32 -> a) -> Maybe -> a
maybe
      (String -> ShowS
showString String
"nothing")
      ( \Int32
i ->
          Bool -> ShowS -> ShowS
showParen (Int
p Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
10) (ShowS -> ShowS) -> ShowS -> ShowS
forall a b. (a -> b) -> a -> b
$
            String -> ShowS
showString String
"just "
              ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Int32 -> ShowS
forall a. Show a => Int -> a -> ShowS
showsPrec Int
11 Int32
i
      )
      Maybe
m

instance Read Maybe where
  readPrec :: ReadPrec Maybe
readPrec = ReadPrec Maybe -> ReadPrec Maybe
forall a. ReadPrec a -> ReadPrec a
parens (ReadPrec Maybe -> ReadPrec Maybe)
-> ReadPrec Maybe -> ReadPrec Maybe
forall a b. (a -> b) -> a -> b
$ ReadPrec Maybe
nothingP ReadPrec Maybe -> ReadPrec Maybe -> ReadPrec Maybe
forall a. ReadPrec a -> ReadPrec a -> ReadPrec a
+++ ReadPrec Maybe
justP
   where
    nothingP :: ReadPrec Maybe
nothingP = do
      Ident String
"nothing" <- ReadPrec Lexeme
lexP
      Maybe -> ReadPrec Maybe
forall a. a -> ReadPrec a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe
nothing
    justP :: ReadPrec Maybe
justP = Int -> ReadPrec Maybe -> ReadPrec Maybe
forall a. Int -> ReadPrec a -> ReadPrec a
prec Int
10 (ReadPrec Maybe -> ReadPrec Maybe)
-> ReadPrec Maybe -> ReadPrec Maybe
forall a b. (a -> b) -> a -> b
$ do
      Ident String
"just" <- ReadPrec Lexeme
lexP
      Int32
a <- ReadPrec Int32 -> ReadPrec Int32
forall a. ReadPrec a -> ReadPrec a
step ReadPrec Int32
forall a. Read a => ReadPrec a
readPrec
      Maybe -> ReadPrec Maybe
forall a. a -> ReadPrec a
forall (m :: * -> *) a. Monad m => a -> m a
return (Int32 -> Maybe
just Int32
a)

listToMaybe :: [Int32] -> Maybe
{-# INLINE listToMaybe #-}
listToMaybe :: [Int32] -> Maybe
listToMaybe [] = Maybe
nothing
listToMaybe (Int32
x : [Int32]
_) = Int32 -> Maybe
just Int32
x

maybeToList :: Maybe -> [Int32]
maybeToList :: Maybe -> [Int32]
maybeToList Maybe
m = [Int32] -> (Int32 -> [Int32]) -> Maybe -> [Int32]
forall a. a -> (Int32 -> a) -> Maybe -> a
maybe [] (Int32 -> [Int32] -> [Int32]
forall a. a -> [a] -> [a]
: []) Maybe
m

catMaybes :: [Maybe] -> [Int32]
catMaybes :: [Maybe] -> [Int32]
catMaybes [Maybe]
ms = (Maybe -> Maybe) -> [Maybe] -> [Int32]
forall a. (a -> Maybe) -> [a] -> [Int32]
mapMaybe Maybe -> Maybe
forall a. a -> a
id [Maybe]
ms

mapMaybe :: (a -> Maybe) -> [a] -> [Int32]
mapMaybe :: forall a. (a -> Maybe) -> [a] -> [Int32]
mapMaybe a -> Maybe
_ [] = []
mapMaybe a -> Maybe
f (a
a : [a]
as) =
  let ws :: [Int32]
ws = (a -> Maybe) -> [a] -> [Int32]
forall a. (a -> Maybe) -> [a] -> [Int32]
mapMaybe a -> Maybe
f [a]
as
   in [Int32] -> (Int32 -> [Int32]) -> Maybe -> [Int32]
forall a. a -> (Int32 -> a) -> Maybe -> a
maybe [Int32]
ws (Int32 -> [Int32] -> [Int32]
forall a. a -> [a] -> [a]
: [Int32]
ws) (a -> Maybe
f a
a)
{-# NOINLINE [1] mapMaybe #-}

{-# RULES
"mapMaybe" [~1] forall f xs.
  mapMaybe f xs =
    build (\c n -> foldr (mapMaybeFB c f) n xs)
"mapMaybeList" [1] forall f. foldr (mapMaybeFB (:) f) [] = mapMaybe f
  #-}

{-# NOINLINE [0] mapMaybeFB #-}
mapMaybeFB :: (Int32 -> r -> r) -> (a -> Maybe) -> a -> r -> r
mapMaybeFB :: forall r a. (Int32 -> r -> r) -> (a -> Maybe) -> a -> r -> r
mapMaybeFB Int32 -> r -> r
cons a -> Maybe
f a
x r
next = r -> (Int32 -> r) -> Maybe -> r
forall a. a -> (Int32 -> a) -> Maybe -> a
maybe r
next ((Int32 -> r -> r) -> r -> Int32 -> r
forall a b c. (a -> b -> c) -> b -> a -> c
flip Int32 -> r -> r
cons r
next) (a -> Maybe
f a
x)

isNothing :: Maybe -> Bool
{-# INLINE isNothing #-}
isNothing :: Maybe -> Bool
isNothing Maybe
m = Bool -> (Int32 -> Bool) -> Maybe -> Bool
forall a. a -> (Int32 -> a) -> Maybe -> a
maybe Bool
True (Bool -> Int32 -> Bool
forall a b. a -> b -> a
const Bool
False) Maybe
m

isJust :: Maybe -> Bool
{-# INLINE isJust #-}
isJust :: Maybe -> Bool
isJust Maybe
m = Bool -> (Int32 -> Bool) -> Maybe -> Bool
forall a. a -> (Int32 -> a) -> Maybe -> a
maybe Bool
False (Bool -> Int32 -> Bool
forall a b. a -> b -> a
const Bool
True) Maybe
m

nothing :: Maybe
{-# INLINE nothing #-}
nothing :: Maybe
nothing = Int# -> Maybe
M Int#
2147483648#

just :: Int32 -> Maybe
{-# INLINE just #-}
just :: Int32 -> Maybe
just (I32# Int#
i) = Int# -> Maybe
M Int#
i

fromMaybe :: Int32 -> Maybe -> Int32
{-# INLINE fromMaybe #-}
fromMaybe :: Int32 -> Maybe -> Int32
fromMaybe Int32
a Maybe
m = Int32 -> (Int32 -> Int32) -> Maybe -> Int32
forall a. a -> (Int32 -> a) -> Maybe -> a
maybe Int32
a Int32 -> Int32
forall a. a -> a
id Maybe
m

maybe :: a -> (Int32 -> a) -> Maybe -> a
{-# INLINE maybe #-}
maybe :: forall a. a -> (Int32 -> a) -> Maybe -> a
maybe a
a Int32 -> a
f (M Int#
m) = case Int#
m Int# -> Int# -> Int#
># Int#
2147483647# of
  Int#
1# -> a
a
  Int#
_ -> case Int#
m Int# -> Int# -> Int#
<# Int#
-2147483648# of
    Int#
1# -> a
a
    Int#
_ -> Int32 -> a
f (Int# -> Int32
I32# Int#
m)

toBaseMaybe :: Maybe -> P.Maybe Int32
{-# INLINE toBaseMaybe #-}
toBaseMaybe :: Maybe -> Maybe Int32
toBaseMaybe Maybe
m = Maybe Int32 -> (Int32 -> Maybe Int32) -> Maybe -> Maybe Int32
forall a. a -> (Int32 -> a) -> Maybe -> a
maybe Maybe Int32
forall a. Maybe a
P.Nothing Int32 -> Maybe Int32
forall a. a -> Maybe a
P.Just Maybe
m

fromBaseMaybe :: P.Maybe Int32 -> Maybe
{-# INLINE fromBaseMaybe #-}
fromBaseMaybe :: Maybe Int32 -> Maybe
fromBaseMaybe Maybe Int32
m = Maybe -> (Int32 -> Maybe) -> Maybe Int32 -> Maybe
forall b a. b -> (a -> b) -> Maybe a -> b
P.maybe Maybe
nothing Int32 -> Maybe
just Maybe Int32
m

pattern Nothing :: Maybe
pattern $mNothing :: forall {r}. Maybe -> ((# #) -> r) -> ((# #) -> r) -> r
$bNothing :: Maybe
Nothing = M 2147483648#

pattern Just :: Int32 -> Maybe
pattern $mJust :: forall {r}. Maybe -> (Int32 -> r) -> ((# #) -> r) -> r
$bJust :: Int32 -> Maybe
Just i <- (maybeInt32ToInt32 -> (# | i #))
  where
    Just (I32# Int#
i) = Int# -> Maybe
M Int#
i

maybeInt32ToInt32 :: Maybe -> (# (# #) | Int32 #)
{-# inline maybeInt32ToInt32 #-}
maybeInt32ToInt32 :: Maybe -> (# (# #) | Int32 #)
maybeInt32ToInt32 (M Int#
i) = case Int#
i of
  Int#
2147483648# -> (# (# #) | #)
  Int#
_ -> (# | Int# -> Int32
I32# Int#
i #)