--------------------------------------------------------------------------------
-- |
-- Module      :  HGeometry.Small.AtMostTwo
-- Copyright   :  (C) Frank Staals
-- License     :  see the LICENSE file
-- Maintainer  :  Frank Staals
--
-- A type expressing that some value may have two or three values
--
--------------------------------------------------------------------------------
module HGeometry.Small.TwoOrThree
  ( TwoOrThree(..), Two, Three, pattern Two, pattern Three
  ) where

import Data.Foldable1
import Data.Bifunctor
import Data.Bitraversable
import Data.Semigroup.Bitraversable
import Data.Semigroup.Bifoldable
import Data.Semigroup.Traversable
import HGeometry.Combinatorial.Util

--------------------------------------------------------------------------------

-- | Either two or three elements
newtype TwoOrThree a = TwoOrThree (Either (Two a) (Three a))
                     deriving (Int -> TwoOrThree a -> ShowS
[TwoOrThree a] -> ShowS
TwoOrThree a -> String
(Int -> TwoOrThree a -> ShowS)
-> (TwoOrThree a -> String)
-> ([TwoOrThree a] -> ShowS)
-> Show (TwoOrThree a)
forall a. Show a => Int -> TwoOrThree a -> ShowS
forall a. Show a => [TwoOrThree a] -> ShowS
forall a. Show a => TwoOrThree a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall a. Show a => Int -> TwoOrThree a -> ShowS
showsPrec :: Int -> TwoOrThree a -> ShowS
$cshow :: forall a. Show a => TwoOrThree a -> String
show :: TwoOrThree a -> String
$cshowList :: forall a. Show a => [TwoOrThree a] -> ShowS
showList :: [TwoOrThree a] -> ShowS
Show,TwoOrThree a -> TwoOrThree a -> Bool
(TwoOrThree a -> TwoOrThree a -> Bool)
-> (TwoOrThree a -> TwoOrThree a -> Bool) -> Eq (TwoOrThree a)
forall a. Eq a => TwoOrThree a -> TwoOrThree a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall a. Eq a => TwoOrThree a -> TwoOrThree a -> Bool
== :: TwoOrThree a -> TwoOrThree a -> Bool
$c/= :: forall a. Eq a => TwoOrThree a -> TwoOrThree a -> Bool
/= :: TwoOrThree a -> TwoOrThree a -> Bool
Eq,Eq (TwoOrThree a)
Eq (TwoOrThree a) =>
(TwoOrThree a -> TwoOrThree a -> Ordering)
-> (TwoOrThree a -> TwoOrThree a -> Bool)
-> (TwoOrThree a -> TwoOrThree a -> Bool)
-> (TwoOrThree a -> TwoOrThree a -> Bool)
-> (TwoOrThree a -> TwoOrThree a -> Bool)
-> (TwoOrThree a -> TwoOrThree a -> TwoOrThree a)
-> (TwoOrThree a -> TwoOrThree a -> TwoOrThree a)
-> Ord (TwoOrThree a)
TwoOrThree a -> TwoOrThree a -> Bool
TwoOrThree a -> TwoOrThree a -> Ordering
TwoOrThree a -> TwoOrThree a -> TwoOrThree 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 (TwoOrThree a)
forall a. Ord a => TwoOrThree a -> TwoOrThree a -> Bool
forall a. Ord a => TwoOrThree a -> TwoOrThree a -> Ordering
forall a. Ord a => TwoOrThree a -> TwoOrThree a -> TwoOrThree a
$ccompare :: forall a. Ord a => TwoOrThree a -> TwoOrThree a -> Ordering
compare :: TwoOrThree a -> TwoOrThree a -> Ordering
$c< :: forall a. Ord a => TwoOrThree a -> TwoOrThree a -> Bool
< :: TwoOrThree a -> TwoOrThree a -> Bool
$c<= :: forall a. Ord a => TwoOrThree a -> TwoOrThree a -> Bool
<= :: TwoOrThree a -> TwoOrThree a -> Bool
$c> :: forall a. Ord a => TwoOrThree a -> TwoOrThree a -> Bool
> :: TwoOrThree a -> TwoOrThree a -> Bool
$c>= :: forall a. Ord a => TwoOrThree a -> TwoOrThree a -> Bool
>= :: TwoOrThree a -> TwoOrThree a -> Bool
$cmax :: forall a. Ord a => TwoOrThree a -> TwoOrThree a -> TwoOrThree a
max :: TwoOrThree a -> TwoOrThree a -> TwoOrThree a
$cmin :: forall a. Ord a => TwoOrThree a -> TwoOrThree a -> TwoOrThree a
min :: TwoOrThree a -> TwoOrThree a -> TwoOrThree a
Ord)

instance Functor TwoOrThree where
  fmap :: forall a b. (a -> b) -> TwoOrThree a -> TwoOrThree b
fmap a -> b
f (TwoOrThree Either (Two a) (Three a)
e) = Either (Two b) (Three b) -> TwoOrThree b
forall a. Either (Two a) (Three a) -> TwoOrThree a
TwoOrThree ((Two a -> Two b)
-> (Three a -> Three b)
-> Either (Two a) (Three a)
-> Either (Two b) (Three b)
forall a b c d. (a -> b) -> (c -> d) -> Either a c -> Either b d
forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap ((a -> b) -> Two a -> Two b
forall a b. (a -> b) -> V2 a -> V2 b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> b
f) ((a -> b) -> Three a -> Three b
forall a b. (a -> b) -> V3 a -> V3 b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> b
f) Either (Two a) (Three a)
e)
instance Foldable1 TwoOrThree where
  foldMap1 :: forall m a. Semigroup m => (a -> m) -> TwoOrThree a -> m
foldMap1 a -> m
f (TwoOrThree Either (Two a) (Three a)
e) = (Two a -> m) -> (Three a -> m) -> Either (Two a) (Three a) -> m
forall m a b.
Semigroup m =>
(a -> m) -> (b -> m) -> Either a b -> m
forall (t :: * -> * -> *) m a b.
(Bifoldable1 t, Semigroup m) =>
(a -> m) -> (b -> m) -> t a b -> m
bifoldMap1 ((a -> m) -> Two a -> m
forall m a. Semigroup m => (a -> m) -> V2 a -> m
forall (t :: * -> *) m a.
(Foldable1 t, Semigroup m) =>
(a -> m) -> t a -> m
foldMap1 a -> m
f) ((a -> m) -> Three a -> m
forall m a. Semigroup m => (a -> m) -> V3 a -> m
forall (t :: * -> *) m a.
(Foldable1 t, Semigroup m) =>
(a -> m) -> t a -> m
foldMap1 a -> m
f) Either (Two a) (Three a)
e
instance Foldable TwoOrThree where
  foldMap :: forall m a. Monoid m => (a -> m) -> TwoOrThree a -> m
foldMap = (a -> m) -> TwoOrThree a -> m
forall m a. Semigroup m => (a -> m) -> TwoOrThree a -> m
forall (t :: * -> *) m a.
(Foldable1 t, Semigroup m) =>
(a -> m) -> t a -> m
foldMap1
instance Traversable1 TwoOrThree where
  traverse1 :: forall (f :: * -> *) a b.
Apply f =>
(a -> f b) -> TwoOrThree a -> f (TwoOrThree b)
traverse1 a -> f b
f (TwoOrThree Either (Two a) (Three a)
e) = Either (Two b) (Three b) -> TwoOrThree b
forall a. Either (Two a) (Three a) -> TwoOrThree a
TwoOrThree (Either (Two b) (Three b) -> TwoOrThree b)
-> f (Either (Two b) (Three b)) -> f (TwoOrThree b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Two a -> f (Two b))
-> (Three a -> f (Three b))
-> Either (Two a) (Three a)
-> f (Either (Two b) (Three b))
forall (f :: * -> *) a b c d.
Apply f =>
(a -> f b) -> (c -> f d) -> Either a c -> f (Either b d)
forall (t :: * -> * -> *) (f :: * -> *) a b c d.
(Bitraversable1 t, Apply f) =>
(a -> f b) -> (c -> f d) -> t a c -> f (t b d)
bitraverse1 ((a -> f b) -> Two a -> f (Two b)
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable1 t, Apply f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b. Apply f => (a -> f b) -> V2 a -> f (V2 b)
traverse1 a -> f b
f) ((a -> f b) -> Three a -> f (Three b)
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable1 t, Apply f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b. Apply f => (a -> f b) -> V3 a -> f (V3 b)
traverse1 a -> f b
f) Either (Two a) (Three a)
e
instance Traversable TwoOrThree where
  traverse :: forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> TwoOrThree a -> f (TwoOrThree b)
traverse a -> f b
f (TwoOrThree Either (Two a) (Three a)
e) = Either (Two b) (Three b) -> TwoOrThree b
forall a. Either (Two a) (Three a) -> TwoOrThree a
TwoOrThree (Either (Two b) (Three b) -> TwoOrThree b)
-> f (Either (Two b) (Three b)) -> f (TwoOrThree b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Two a -> f (Two b))
-> (Three a -> f (Three b))
-> Either (Two a) (Three a)
-> f (Either (Two b) (Three b))
forall (f :: * -> *) a c b d.
Applicative f =>
(a -> f c) -> (b -> f d) -> Either a b -> f (Either c d)
forall (t :: * -> * -> *) (f :: * -> *) a c b d.
(Bitraversable t, Applicative f) =>
(a -> f c) -> (b -> f d) -> t a b -> f (t c d)
bitraverse ((a -> f b) -> Two a -> f (Two b)
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> V2 a -> f (V2 b)
traverse a -> f b
f) ((a -> f b) -> Three a -> f (Three b)
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> V3 a -> f (V3 b)
traverse a -> f b
f) Either (Two a) (Three a)
e