{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE UnboxedSums #-}
{-# LANGUAGE UnboxedTuples #-}

module Data.Maybe.Unpacked.Numeric.Int8
  ( Maybe(..)
  , just
  , nothing

  , maybe

  , isJust
  , isNothing
  , fromMaybe
  , listToMaybe
  , maybeToList
  , catMaybes
  , mapMaybe

  , toBaseMaybe
  , fromBaseMaybe
  ) where

import Prelude hiding (Maybe,maybe)

import GHC.Exts 
import GHC.Int (Int8)
import GHC.Int.Compat (pattern I8#)

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

import qualified Prelude as P

data Maybe = M Int#

instance Eq Maybe where
  Maybe
ma == :: Maybe -> Maybe -> Bool
== Maybe
mb =
    forall a. a -> (Int8 -> a) -> Maybe -> a
maybe (Maybe -> Bool
isNothing Maybe
mb)
          (\Int8
a -> forall a. a -> (Int8 -> a) -> Maybe -> a
maybe Bool
False (\Int8
b -> Int8
a forall a. Eq a => a -> a -> Bool
== Int8
b) Maybe
mb) Maybe
ma
    
instance Ord Maybe where
  compare :: Maybe -> Maybe -> Ordering
compare Maybe
ma Maybe
mb = forall a. a -> (Int8 -> a) -> Maybe -> a
maybe Ordering
LT (\Int8
a -> forall a. a -> (Int8 -> a) -> Maybe -> a
maybe Ordering
GT (forall a. Ord a => a -> a -> Ordering
compare Int8
a) Maybe
mb) Maybe
ma  

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

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

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

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

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

mapMaybe :: (a -> Maybe) -> [a] -> [Int8]
mapMaybe :: forall a. (a -> Maybe) -> [a] -> [Int8]
mapMaybe a -> Maybe
_ [] = []
mapMaybe a -> Maybe
f (a
a : [a]
as) =
  let ws :: [Int8]
ws = forall a. (a -> Maybe) -> [a] -> [Int8]
mapMaybe a -> Maybe
f [a]
as
  in forall a. a -> (Int8 -> a) -> Maybe -> a
maybe [Int8]
ws (forall a. a -> [a] -> [a]
: [Int8]
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 :: (Int8 -> r -> r) -> (a -> Maybe) -> a -> r -> r
mapMaybeFB :: forall r a. (Int8 -> r -> r) -> (a -> Maybe) -> a -> r -> r
mapMaybeFB Int8 -> r -> r
cons a -> Maybe
f a
x r
next = forall a. a -> (Int8 -> a) -> Maybe -> a
maybe r
next (forall a b c. (a -> b -> c) -> b -> a -> c
flip Int8 -> r -> r
cons r
next) (a -> Maybe
f a
x)

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

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

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

just :: Int8 -> Maybe
{-# INLINE just #-}
just :: Int8 -> Maybe
just (I8# Int#
i) = Int# -> Maybe
M Int#
i

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

maybe :: a -> (Int8 -> a) -> Maybe -> a
{-# INLINE maybe #-}
maybe :: forall a. a -> (Int8 -> a) -> Maybe -> a
maybe a
a Int8 -> a
f (M Int#
m) = case Int#
m Int# -> Int# -> Int#
># Int#
127# of
  Int#
1# -> a
a
  Int#
_  -> case Int#
m Int# -> Int# -> Int#
<# Int#
-128# of
    Int#
1# -> a
a
    Int#
_  -> Int8 -> a
f (Int# -> Int8
I8# Int#
m)

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

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