-- | Option types are similar to @Maybe a@, @Maybe (a, b)@ and so on, 
--   except they are directly unpacked into the constructor and are
--   strict in each component.
--
module Data.Repa.Scalar.Option
        ( -- * Single component
          Option  (..)
        , fromOption,  toOption

          -- * Two components
        , Option2 (..)
        , fromOption2, toOption2

          -- * Three components
        , Option3 (..)
        , fromOption3, toOption3

          -- * Four components
        , Option4 (..)
        , fromOption4, toOption4)
where


-------------------------------------------------------------------------------
-- | A strict `Maybe` type.
data Option a
        = Some !a
        | None 
        deriving (Option a -> Option a -> Bool
(Option a -> Option a -> Bool)
-> (Option a -> Option a -> Bool) -> Eq (Option a)
forall a. Eq a => Option a -> Option a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall a. Eq a => Option a -> Option a -> Bool
== :: Option a -> Option a -> Bool
$c/= :: forall a. Eq a => Option a -> Option a -> Bool
/= :: Option a -> Option a -> Bool
Eq, Eq (Option a)
Eq (Option a) =>
(Option a -> Option a -> Ordering)
-> (Option a -> Option a -> Bool)
-> (Option a -> Option a -> Bool)
-> (Option a -> Option a -> Bool)
-> (Option a -> Option a -> Bool)
-> (Option a -> Option a -> Option a)
-> (Option a -> Option a -> Option a)
-> Ord (Option a)
Option a -> Option a -> Bool
Option a -> Option a -> Ordering
Option a -> Option a -> Option a
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall a. Ord a => Eq (Option a)
forall a. Ord a => Option a -> Option a -> Bool
forall a. Ord a => Option a -> Option a -> Ordering
forall a. Ord a => Option a -> Option a -> Option a
$ccompare :: forall a. Ord a => Option a -> Option a -> Ordering
compare :: Option a -> Option a -> Ordering
$c< :: forall a. Ord a => Option a -> Option a -> Bool
< :: Option a -> Option a -> Bool
$c<= :: forall a. Ord a => Option a -> Option a -> Bool
<= :: Option a -> Option a -> Bool
$c> :: forall a. Ord a => Option a -> Option a -> Bool
> :: Option a -> Option a -> Bool
$c>= :: forall a. Ord a => Option a -> Option a -> Bool
>= :: Option a -> Option a -> Bool
$cmax :: forall a. Ord a => Option a -> Option a -> Option a
max :: Option a -> Option a -> Option a
$cmin :: forall a. Ord a => Option a -> Option a -> Option a
min :: Option a -> Option a -> Option a
Ord, Int -> Option a -> ShowS
[Option a] -> ShowS
Option a -> String
(Int -> Option a -> ShowS)
-> (Option a -> String) -> ([Option a] -> ShowS) -> Show (Option a)
forall a. Show a => Int -> Option a -> ShowS
forall a. Show a => [Option a] -> ShowS
forall a. Show a => Option a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall a. Show a => Int -> Option a -> ShowS
showsPrec :: Int -> Option a -> ShowS
$cshow :: forall a. Show a => Option a -> String
show :: Option a -> String
$cshowList :: forall a. Show a => [Option a] -> ShowS
showList :: [Option a] -> ShowS
Show)


-- | Convert a `Maybe` to an `Option`.
toOption :: Maybe a -> Option a
toOption :: forall a. Maybe a -> Option a
toOption Maybe a
Nothing        = Option a
forall a. Option a
None
toOption (Just a
x)       = a -> Option a
forall a. a -> Option a
Some a
x
{-# INLINE toOption #-}


-- | Convert an `Option` to a `Maybe`.
fromOption :: Option a -> Maybe a
fromOption :: forall a. Option a -> Maybe a
fromOption Option a
None         = Maybe a
forall a. Maybe a
Nothing
fromOption (Some a
x)     = a -> Maybe a
forall a. a -> Maybe a
Just a
x
{-# INLINE fromOption #-}


instance Functor Option where
 fmap :: forall a b. (a -> b) -> Option a -> Option b
fmap a -> b
_ Option a
None     = Option b
forall a. Option a
None
 fmap a -> b
f (Some a
x) = b -> Option b
forall a. a -> Option a
Some (a -> b
f a
x)
 {-# INLINE fmap #-}


-------------------------------------------------------------------------------
-- | A strict `Maybe` type, with two parameters.
data Option2 a b
        = Some2 !a !b
        | None2 
        deriving (Option2 a b -> Option2 a b -> Bool
(Option2 a b -> Option2 a b -> Bool)
-> (Option2 a b -> Option2 a b -> Bool) -> Eq (Option2 a b)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall a b. (Eq a, Eq b) => Option2 a b -> Option2 a b -> Bool
$c== :: forall a b. (Eq a, Eq b) => Option2 a b -> Option2 a b -> Bool
== :: Option2 a b -> Option2 a b -> Bool
$c/= :: forall a b. (Eq a, Eq b) => Option2 a b -> Option2 a b -> Bool
/= :: Option2 a b -> Option2 a b -> Bool
Eq, Eq (Option2 a b)
Eq (Option2 a b) =>
(Option2 a b -> Option2 a b -> Ordering)
-> (Option2 a b -> Option2 a b -> Bool)
-> (Option2 a b -> Option2 a b -> Bool)
-> (Option2 a b -> Option2 a b -> Bool)
-> (Option2 a b -> Option2 a b -> Bool)
-> (Option2 a b -> Option2 a b -> Option2 a b)
-> (Option2 a b -> Option2 a b -> Option2 a b)
-> Ord (Option2 a b)
Option2 a b -> Option2 a b -> Bool
Option2 a b -> Option2 a b -> Ordering
Option2 a b -> Option2 a b -> Option2 a b
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall a b. (Ord a, Ord b) => Eq (Option2 a b)
forall a b. (Ord a, Ord b) => Option2 a b -> Option2 a b -> Bool
forall a b.
(Ord a, Ord b) =>
Option2 a b -> Option2 a b -> Ordering
forall a b.
(Ord a, Ord b) =>
Option2 a b -> Option2 a b -> Option2 a b
$ccompare :: forall a b.
(Ord a, Ord b) =>
Option2 a b -> Option2 a b -> Ordering
compare :: Option2 a b -> Option2 a b -> Ordering
$c< :: forall a b. (Ord a, Ord b) => Option2 a b -> Option2 a b -> Bool
< :: Option2 a b -> Option2 a b -> Bool
$c<= :: forall a b. (Ord a, Ord b) => Option2 a b -> Option2 a b -> Bool
<= :: Option2 a b -> Option2 a b -> Bool
$c> :: forall a b. (Ord a, Ord b) => Option2 a b -> Option2 a b -> Bool
> :: Option2 a b -> Option2 a b -> Bool
$c>= :: forall a b. (Ord a, Ord b) => Option2 a b -> Option2 a b -> Bool
>= :: Option2 a b -> Option2 a b -> Bool
$cmax :: forall a b.
(Ord a, Ord b) =>
Option2 a b -> Option2 a b -> Option2 a b
max :: Option2 a b -> Option2 a b -> Option2 a b
$cmin :: forall a b.
(Ord a, Ord b) =>
Option2 a b -> Option2 a b -> Option2 a b
min :: Option2 a b -> Option2 a b -> Option2 a b
Ord, Int -> Option2 a b -> ShowS
[Option2 a b] -> ShowS
Option2 a b -> String
(Int -> Option2 a b -> ShowS)
-> (Option2 a b -> String)
-> ([Option2 a b] -> ShowS)
-> Show (Option2 a b)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall a b. (Show a, Show b) => Int -> Option2 a b -> ShowS
forall a b. (Show a, Show b) => [Option2 a b] -> ShowS
forall a b. (Show a, Show b) => Option2 a b -> String
$cshowsPrec :: forall a b. (Show a, Show b) => Int -> Option2 a b -> ShowS
showsPrec :: Int -> Option2 a b -> ShowS
$cshow :: forall a b. (Show a, Show b) => Option2 a b -> String
show :: Option2 a b -> String
$cshowList :: forall a b. (Show a, Show b) => [Option2 a b] -> ShowS
showList :: [Option2 a b] -> ShowS
Show)


-- | Convert a `Maybe` to an `Option2`.
toOption2 :: Maybe (a, b) -> Option2 a b
toOption2 :: forall a b. Maybe (a, b) -> Option2 a b
toOption2 Maybe (a, b)
Nothing        = Option2 a b
forall a b. Option2 a b
None2
toOption2 (Just (a
x, b
y))  = a -> b -> Option2 a b
forall a b. a -> b -> Option2 a b
Some2 a
x b
y
{-# INLINE toOption2 #-}


-- | Convert an `Option2` to a `Maybe`.
fromOption2 :: Option2 a b -> Maybe (a, b)
fromOption2 :: forall a b. Option2 a b -> Maybe (a, b)
fromOption2 Option2 a b
None2        = Maybe (a, b)
forall a. Maybe a
Nothing
fromOption2 (Some2 a
x b
y)  = (a, b) -> Maybe (a, b)
forall a. a -> Maybe a
Just (a
x, b
y)
{-# INLINE fromOption2 #-}


instance Functor (Option2 a) where
 fmap :: forall a b. (a -> b) -> Option2 a a -> Option2 a b
fmap a -> b
_ Option2 a a
None2       = Option2 a b
forall a b. Option2 a b
None2
 fmap a -> b
f (Some2 a
x a
y) = a -> b -> Option2 a b
forall a b. a -> b -> Option2 a b
Some2 a
x (a -> b
f a
y)
 {-# INLINE fmap #-}


-------------------------------------------------------------------------------
-- | A strict `Maybe` type with three parameters.
data Option3 a b c
        = Some3 !a !b !c
        | None3 
        deriving (Option3 a b c -> Option3 a b c -> Bool
(Option3 a b c -> Option3 a b c -> Bool)
-> (Option3 a b c -> Option3 a b c -> Bool) -> Eq (Option3 a b c)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall a b c.
(Eq a, Eq b, Eq c) =>
Option3 a b c -> Option3 a b c -> Bool
$c== :: forall a b c.
(Eq a, Eq b, Eq c) =>
Option3 a b c -> Option3 a b c -> Bool
== :: Option3 a b c -> Option3 a b c -> Bool
$c/= :: forall a b c.
(Eq a, Eq b, Eq c) =>
Option3 a b c -> Option3 a b c -> Bool
/= :: Option3 a b c -> Option3 a b c -> Bool
Eq, Eq (Option3 a b c)
Eq (Option3 a b c) =>
(Option3 a b c -> Option3 a b c -> Ordering)
-> (Option3 a b c -> Option3 a b c -> Bool)
-> (Option3 a b c -> Option3 a b c -> Bool)
-> (Option3 a b c -> Option3 a b c -> Bool)
-> (Option3 a b c -> Option3 a b c -> Bool)
-> (Option3 a b c -> Option3 a b c -> Option3 a b c)
-> (Option3 a b c -> Option3 a b c -> Option3 a b c)
-> Ord (Option3 a b c)
Option3 a b c -> Option3 a b c -> Bool
Option3 a b c -> Option3 a b c -> Ordering
Option3 a b c -> Option3 a b c -> Option3 a b c
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall a b c. (Ord a, Ord b, Ord c) => Eq (Option3 a b c)
forall a b c.
(Ord a, Ord b, Ord c) =>
Option3 a b c -> Option3 a b c -> Bool
forall a b c.
(Ord a, Ord b, Ord c) =>
Option3 a b c -> Option3 a b c -> Ordering
forall a b c.
(Ord a, Ord b, Ord c) =>
Option3 a b c -> Option3 a b c -> Option3 a b c
$ccompare :: forall a b c.
(Ord a, Ord b, Ord c) =>
Option3 a b c -> Option3 a b c -> Ordering
compare :: Option3 a b c -> Option3 a b c -> Ordering
$c< :: forall a b c.
(Ord a, Ord b, Ord c) =>
Option3 a b c -> Option3 a b c -> Bool
< :: Option3 a b c -> Option3 a b c -> Bool
$c<= :: forall a b c.
(Ord a, Ord b, Ord c) =>
Option3 a b c -> Option3 a b c -> Bool
<= :: Option3 a b c -> Option3 a b c -> Bool
$c> :: forall a b c.
(Ord a, Ord b, Ord c) =>
Option3 a b c -> Option3 a b c -> Bool
> :: Option3 a b c -> Option3 a b c -> Bool
$c>= :: forall a b c.
(Ord a, Ord b, Ord c) =>
Option3 a b c -> Option3 a b c -> Bool
>= :: Option3 a b c -> Option3 a b c -> Bool
$cmax :: forall a b c.
(Ord a, Ord b, Ord c) =>
Option3 a b c -> Option3 a b c -> Option3 a b c
max :: Option3 a b c -> Option3 a b c -> Option3 a b c
$cmin :: forall a b c.
(Ord a, Ord b, Ord c) =>
Option3 a b c -> Option3 a b c -> Option3 a b c
min :: Option3 a b c -> Option3 a b c -> Option3 a b c
Ord, Int -> Option3 a b c -> ShowS
[Option3 a b c] -> ShowS
Option3 a b c -> String
(Int -> Option3 a b c -> ShowS)
-> (Option3 a b c -> String)
-> ([Option3 a b c] -> ShowS)
-> Show (Option3 a b c)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall a b c.
(Show a, Show b, Show c) =>
Int -> Option3 a b c -> ShowS
forall a b c. (Show a, Show b, Show c) => [Option3 a b c] -> ShowS
forall a b c. (Show a, Show b, Show c) => Option3 a b c -> String
$cshowsPrec :: forall a b c.
(Show a, Show b, Show c) =>
Int -> Option3 a b c -> ShowS
showsPrec :: Int -> Option3 a b c -> ShowS
$cshow :: forall a b c. (Show a, Show b, Show c) => Option3 a b c -> String
show :: Option3 a b c -> String
$cshowList :: forall a b c. (Show a, Show b, Show c) => [Option3 a b c] -> ShowS
showList :: [Option3 a b c] -> ShowS
Show)


-- | Convert a `Maybe` to an `Option3`.
toOption3 :: Maybe (a, b, c) -> Option3 a b c
toOption3 :: forall a b c. Maybe (a, b, c) -> Option3 a b c
toOption3 Maybe (a, b, c)
Nothing          = Option3 a b c
forall a b c. Option3 a b c
None3
toOption3 (Just (a
x, b
y, c
z)) = a -> b -> c -> Option3 a b c
forall a b c. a -> b -> c -> Option3 a b c
Some3 a
x b
y c
z
{-# INLINE toOption3 #-}


-- | Convert an `Option2` to a `Maybe`.
fromOption3 :: Option3 a b c -> Maybe (a, b, c)
fromOption3 :: forall a b c. Option3 a b c -> Maybe (a, b, c)
fromOption3 Option3 a b c
None3          = Maybe (a, b, c)
forall a. Maybe a
Nothing
fromOption3 (Some3 a
x b
y c
z)  = (a, b, c) -> Maybe (a, b, c)
forall a. a -> Maybe a
Just (a
x, b
y, c
z)
{-# INLINE fromOption3 #-}


instance Functor (Option3 a b) where
 fmap :: forall a b. (a -> b) -> Option3 a b a -> Option3 a b b
fmap a -> b
_ Option3 a b a
None3         = Option3 a b b
forall a b c. Option3 a b c
None3
 fmap a -> b
f (Some3 a
x b
y a
z) = a -> b -> b -> Option3 a b b
forall a b c. a -> b -> c -> Option3 a b c
Some3 a
x b
y (a -> b
f a
z)
 {-# INLINE fmap #-}


-------------------------------------------------------------------------------
-- | A strict `Maybe` type with four parameters.
data Option4 a b c d
        = Some4 !a !b !c !d
        | None4 
        deriving (Option4 a b c d -> Option4 a b c d -> Bool
(Option4 a b c d -> Option4 a b c d -> Bool)
-> (Option4 a b c d -> Option4 a b c d -> Bool)
-> Eq (Option4 a b c d)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall a b c d.
(Eq a, Eq b, Eq c, Eq d) =>
Option4 a b c d -> Option4 a b c d -> Bool
$c== :: forall a b c d.
(Eq a, Eq b, Eq c, Eq d) =>
Option4 a b c d -> Option4 a b c d -> Bool
== :: Option4 a b c d -> Option4 a b c d -> Bool
$c/= :: forall a b c d.
(Eq a, Eq b, Eq c, Eq d) =>
Option4 a b c d -> Option4 a b c d -> Bool
/= :: Option4 a b c d -> Option4 a b c d -> Bool
Eq, Eq (Option4 a b c d)
Eq (Option4 a b c d) =>
(Option4 a b c d -> Option4 a b c d -> Ordering)
-> (Option4 a b c d -> Option4 a b c d -> Bool)
-> (Option4 a b c d -> Option4 a b c d -> Bool)
-> (Option4 a b c d -> Option4 a b c d -> Bool)
-> (Option4 a b c d -> Option4 a b c d -> Bool)
-> (Option4 a b c d -> Option4 a b c d -> Option4 a b c d)
-> (Option4 a b c d -> Option4 a b c d -> Option4 a b c d)
-> Ord (Option4 a b c d)
Option4 a b c d -> Option4 a b c d -> Bool
Option4 a b c d -> Option4 a b c d -> Ordering
Option4 a b c d -> Option4 a b c d -> Option4 a b c d
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall a b c d.
(Ord a, Ord b, Ord c, Ord d) =>
Eq (Option4 a b c d)
forall a b c d.
(Ord a, Ord b, Ord c, Ord d) =>
Option4 a b c d -> Option4 a b c d -> Bool
forall a b c d.
(Ord a, Ord b, Ord c, Ord d) =>
Option4 a b c d -> Option4 a b c d -> Ordering
forall a b c d.
(Ord a, Ord b, Ord c, Ord d) =>
Option4 a b c d -> Option4 a b c d -> Option4 a b c d
$ccompare :: forall a b c d.
(Ord a, Ord b, Ord c, Ord d) =>
Option4 a b c d -> Option4 a b c d -> Ordering
compare :: Option4 a b c d -> Option4 a b c d -> Ordering
$c< :: forall a b c d.
(Ord a, Ord b, Ord c, Ord d) =>
Option4 a b c d -> Option4 a b c d -> Bool
< :: Option4 a b c d -> Option4 a b c d -> Bool
$c<= :: forall a b c d.
(Ord a, Ord b, Ord c, Ord d) =>
Option4 a b c d -> Option4 a b c d -> Bool
<= :: Option4 a b c d -> Option4 a b c d -> Bool
$c> :: forall a b c d.
(Ord a, Ord b, Ord c, Ord d) =>
Option4 a b c d -> Option4 a b c d -> Bool
> :: Option4 a b c d -> Option4 a b c d -> Bool
$c>= :: forall a b c d.
(Ord a, Ord b, Ord c, Ord d) =>
Option4 a b c d -> Option4 a b c d -> Bool
>= :: Option4 a b c d -> Option4 a b c d -> Bool
$cmax :: forall a b c d.
(Ord a, Ord b, Ord c, Ord d) =>
Option4 a b c d -> Option4 a b c d -> Option4 a b c d
max :: Option4 a b c d -> Option4 a b c d -> Option4 a b c d
$cmin :: forall a b c d.
(Ord a, Ord b, Ord c, Ord d) =>
Option4 a b c d -> Option4 a b c d -> Option4 a b c d
min :: Option4 a b c d -> Option4 a b c d -> Option4 a b c d
Ord, Int -> Option4 a b c d -> ShowS
[Option4 a b c d] -> ShowS
Option4 a b c d -> String
(Int -> Option4 a b c d -> ShowS)
-> (Option4 a b c d -> String)
-> ([Option4 a b c d] -> ShowS)
-> Show (Option4 a b c d)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall a b c d.
(Show a, Show b, Show c, Show d) =>
Int -> Option4 a b c d -> ShowS
forall a b c d.
(Show a, Show b, Show c, Show d) =>
[Option4 a b c d] -> ShowS
forall a b c d.
(Show a, Show b, Show c, Show d) =>
Option4 a b c d -> String
$cshowsPrec :: forall a b c d.
(Show a, Show b, Show c, Show d) =>
Int -> Option4 a b c d -> ShowS
showsPrec :: Int -> Option4 a b c d -> ShowS
$cshow :: forall a b c d.
(Show a, Show b, Show c, Show d) =>
Option4 a b c d -> String
show :: Option4 a b c d -> String
$cshowList :: forall a b c d.
(Show a, Show b, Show c, Show d) =>
[Option4 a b c d] -> ShowS
showList :: [Option4 a b c d] -> ShowS
Show)


-- | Convert a `Maybe` to an `Option4`.
toOption4 :: Maybe (a, b, c, d) -> Option4 a b c d
toOption4 :: forall a b c d. Maybe (a, b, c, d) -> Option4 a b c d
toOption4 Maybe (a, b, c, d)
Nothing                 = Option4 a b c d
forall a b c d. Option4 a b c d
None4
toOption4 (Just (a
x1, b
x2, c
x3, d
x4)) = a -> b -> c -> d -> Option4 a b c d
forall a b c d. a -> b -> c -> d -> Option4 a b c d
Some4 a
x1 b
x2 c
x3 d
x4
{-# INLINE toOption4 #-}


-- | Convert an `Option2` to a `Maybe`.
fromOption4 :: Option4 a b c d -> Maybe (a, b, c, d)
fromOption4 :: forall a b c d. Option4 a b c d -> Maybe (a, b, c, d)
fromOption4 Option4 a b c d
None4                 = Maybe (a, b, c, d)
forall a. Maybe a
Nothing
fromOption4 (Some4 a
x1 b
x2 c
x3 d
x4)   = (a, b, c, d) -> Maybe (a, b, c, d)
forall a. a -> Maybe a
Just (a
x1, b
x2, c
x3, d
x4)
{-# INLINE fromOption4 #-}


instance Functor (Option4 a b c) where
 fmap :: forall a b. (a -> b) -> Option4 a b c a -> Option4 a b c b
fmap a -> b
_ Option4 a b c a
None4           = Option4 a b c b
forall a b c d. Option4 a b c d
None4
 fmap a -> b
f (Some4 a
x b
y c
z a
a) = a -> b -> c -> b -> Option4 a b c b
forall a b c d. a -> b -> c -> d -> Option4 a b c d
Some4 a
x b
y c
z (a -> b
f a
a)
 {-# INLINE fmap #-}