{-# LANGUAGE NoImplicitPrelude #-}

module Data.Digit.Char(
-- * Binary
  charBinaryNoZero
, charBinary
-- * Octal
, charOctalNoZero
, charOctal
-- * Decimal
, charDecimalNoZero
, charDecimal
-- * Hexadecimal
, charHexadecimalNoZero
, charHexadecimal
-- * HEXADECIMAL
, charHEXADECIMALNoZero
, charHEXADECIMAL
-- * HeXaDeCiMaL
, charHeXaDeCiMaLNoZero
, charHeXaDeCiMaL
) where

import           Prelude                (Char, Eq, fst, lookup)

import           Control.Applicative    (Applicative)
import           Control.Lens           (APrism, Choice, Prism', clonePrism,
                                         prism', ( # ))
import           Control.Lens.Extras    (is)

import           Data.Foldable          (find)
import           Data.Functor           ((<$>))
import           Data.Maybe             (fromMaybe)

import           Data.Digit.Binary      as D
import           Data.Digit.Decimal     as D
import           Data.Digit.Hexadecimal.LowerCase as D
import           Data.Digit.Hexadecimal.UpperCase as D
import           Data.Digit.Hexadecimal.MixedCase as D
import           Data.Digit.Octal       as D

-- $setup
-- >>> import Data.Digit

-- |
--
-- >>> '1' ^? charBinaryNoZero :: Maybe BinDigit
-- Just BinDigit1
--
-- >>> charBinaryNoZero # BinDigit1
-- '1'
charBinaryNoZero ::
  BinaryNoZero d =>
  Prism'
    Char
    d
charBinaryNoZero :: forall d. BinaryNoZero d => Prism' Char d
charBinaryNoZero =
  forall b (p :: * -> * -> *) (f :: * -> *) a.
(Eq b, Choice p, Applicative f) =>
(b, APrism a a () ())
-> [(b, APrism a a () ())] -> p a (f a) -> p b (f b)
associatePrism (Char
'1', forall d. D1 d => Prism' d ()
d1) []

-- |
--
-- >>> '0' ^? charBinary :: Maybe BinDigit
-- Just BinDigit0
--
-- >>> charBinary # BinDigit0 :: Char
-- '0'
charBinary ::
  Binary d =>
  Prism'
    Char
    d
charBinary :: forall d. Binary d => Prism' Char d
charBinary =
  forall b (p :: * -> * -> *) (f :: * -> *) a.
(Eq b, Choice p, Applicative f) =>
(b, APrism a a () ())
-> [(b, APrism a a () ())] -> p a (f a) -> p b (f b)
associatePrism (Char
'0', forall d. D0 d => Prism' d ()
d0) [(Char
'1', forall d. D1 d => Prism' d ()
d1)]

-- |
--
-- >>> '6' ^? charOctalNoZero :: Maybe OctDigit
-- Just OctDigit6
--
-- >>> charOctalNoZero # OctDigit5 :: Char
-- '5'
charOctalNoZero ::
  OctalNoZero d =>
  Prism'
    Char
    d
charOctalNoZero :: forall d. OctalNoZero d => Prism' Char d
charOctalNoZero =
  forall b (p :: * -> * -> *) (f :: * -> *) a.
(Eq b, Choice p, Applicative f) =>
(b, APrism a a () ())
-> [(b, APrism a a () ())] -> p a (f a) -> p b (f b)
associatePrism (Char
'1', forall d. D1 d => Prism' d ()
d1) [(Char
'2', forall d. D2 d => Prism' d ()
d2), (Char
'3', forall d. D3 d => Prism' d ()
d3), (Char
'4', forall d. D4 d => Prism' d ()
d4), (Char
'5', forall d. D5 d => Prism' d ()
d5), (Char
'6', forall d. D6 d => Prism' d ()
d6), (Char
'7', forall d. D7 d => Prism' d ()
d7)]

-- |
-- >>> '7' ^? charOctal :: Maybe OctDigit
-- Just OctDigit7
--
-- >>> charOctal # OctDigit7 :: Char
-- '7'
charOctal ::
  Octal d =>
  Prism'
    Char
    d
charOctal :: forall d. Octal d => Prism' Char d
charOctal =
  forall b (p :: * -> * -> *) (f :: * -> *) a.
(Eq b, Choice p, Applicative f) =>
(b, APrism a a () ())
-> [(b, APrism a a () ())] -> p a (f a) -> p b (f b)
associatePrism (Char
'0', forall d. D0 d => Prism' d ()
d0) [(Char
'1', forall d. D1 d => Prism' d ()
d1), (Char
'2', forall d. D2 d => Prism' d ()
d2), (Char
'3', forall d. D3 d => Prism' d ()
d3), (Char
'4', forall d. D4 d => Prism' d ()
d4), (Char
'5', forall d. D5 d => Prism' d ()
d5), (Char
'6', forall d. D6 d => Prism' d ()
d6), (Char
'7', forall d. D7 d => Prism' d ()
d7)]

-- |
-- >>> '9' ^? charDecimalNoZero :: Maybe DecDigit
-- Just DecDigit9
--
-- >>> charDecimalNoZero # DecDigit9 :: Char
-- '9'
charDecimalNoZero ::
  DecimalNoZero d =>
  Prism'
    Char
    d
charDecimalNoZero :: forall d. DecimalNoZero d => Prism' Char d
charDecimalNoZero =
  forall b (p :: * -> * -> *) (f :: * -> *) a.
(Eq b, Choice p, Applicative f) =>
(b, APrism a a () ())
-> [(b, APrism a a () ())] -> p a (f a) -> p b (f b)
associatePrism (Char
'1', forall d. D1 d => Prism' d ()
d1) [(Char
'2', forall d. D2 d => Prism' d ()
d2), (Char
'3', forall d. D3 d => Prism' d ()
d3), (Char
'4', forall d. D4 d => Prism' d ()
d4), (Char
'5', forall d. D5 d => Prism' d ()
d5), (Char
'6', forall d. D6 d => Prism' d ()
d6), (Char
'7', forall d. D7 d => Prism' d ()
d7), (Char
'8', forall d. D8 d => Prism' d ()
d8), (Char
'9', forall d. D9 d => Prism' d ()
d9)]

-- |
-- >>> '9' ^? charDecimal :: Maybe DecDigit
-- Just DecDigit9
--
-- >>> charDecimal # DecDigit9 :: Char
-- '9'
charDecimal ::
  Decimal d =>
  Prism'
    Char
    d
charDecimal :: forall d. Decimal d => Prism' Char d
charDecimal =
  forall b (p :: * -> * -> *) (f :: * -> *) a.
(Eq b, Choice p, Applicative f) =>
(b, APrism a a () ())
-> [(b, APrism a a () ())] -> p a (f a) -> p b (f b)
associatePrism (Char
'0', forall d. D0 d => Prism' d ()
d0) [(Char
'1', forall d. D1 d => Prism' d ()
d1), (Char
'2', forall d. D2 d => Prism' d ()
d2), (Char
'3', forall d. D3 d => Prism' d ()
d3), (Char
'4', forall d. D4 d => Prism' d ()
d4), (Char
'5', forall d. D5 d => Prism' d ()
d5), (Char
'6', forall d. D6 d => Prism' d ()
d6), (Char
'7', forall d. D7 d => Prism' d ()
d7), (Char
'8', forall d. D8 d => Prism' d ()
d8), (Char
'9', forall d. D9 d => Prism' d ()
d9)]

-- |
-- >>> 'f' ^? charHexadecimalNoZero :: Maybe HexDigit
-- Just HexDigitf
--
-- >>> charHexadecimalNoZero # HexDigitf :: Char
-- 'f'
charHexadecimalNoZero ::
  HexadecimalNoZero d =>
  Prism'
    Char
    d
charHexadecimalNoZero :: forall d. HexadecimalNoZero d => Prism' Char d
charHexadecimalNoZero =
  forall b (p :: * -> * -> *) (f :: * -> *) a.
(Eq b, Choice p, Applicative f) =>
(b, APrism a a () ())
-> [(b, APrism a a () ())] -> p a (f a) -> p b (f b)
associatePrism (Char
'1', forall d. D1 d => Prism' d ()
d1) [(Char
'2', forall d. D2 d => Prism' d ()
d2), (Char
'3', forall d. D3 d => Prism' d ()
d3), (Char
'4', forall d. D4 d => Prism' d ()
d4), (Char
'5', forall d. D5 d => Prism' d ()
d5), (Char
'6', forall d. D6 d => Prism' d ()
d6), (Char
'7', forall d. D7 d => Prism' d ()
d7), (Char
'8', forall d. D8 d => Prism' d ()
d8), (Char
'9', forall d. D9 d => Prism' d ()
d9), (Char
'a', forall d. Da d => Prism' d ()
da), (Char
'b', forall d. Db d => Prism' d ()
db), (Char
'c', forall d. Dc d => Prism' d ()
dc), (Char
'd', forall d. Dd d => Prism' d ()
dd), (Char
'e', forall d. De d => Prism' d ()
de), (Char
'f', forall d. Df d => Prism' d ()
df)]

-- |
-- >>> 'f' ^? charHexadecimal :: Maybe HexDigit
-- Just HexDigitf
--
-- >>> charHexadecimal # HexDigitf :: Char
-- 'f'
charHexadecimal ::
  Hexadecimal d =>
  Prism'
    Char
    d
charHexadecimal :: forall d. Hexadecimal d => Prism' Char d
charHexadecimal =
  forall b (p :: * -> * -> *) (f :: * -> *) a.
(Eq b, Choice p, Applicative f) =>
(b, APrism a a () ())
-> [(b, APrism a a () ())] -> p a (f a) -> p b (f b)
associatePrism (Char
'0', forall d. D0 d => Prism' d ()
d0) [(Char
'1', forall d. D1 d => Prism' d ()
d1), (Char
'2', forall d. D2 d => Prism' d ()
d2), (Char
'3', forall d. D3 d => Prism' d ()
d3), (Char
'4', forall d. D4 d => Prism' d ()
d4), (Char
'5', forall d. D5 d => Prism' d ()
d5), (Char
'6', forall d. D6 d => Prism' d ()
d6), (Char
'7', forall d. D7 d => Prism' d ()
d7), (Char
'8', forall d. D8 d => Prism' d ()
d8), (Char
'9', forall d. D9 d => Prism' d ()
d9), (Char
'a', forall d. Da d => Prism' d ()
da), (Char
'b', forall d. Db d => Prism' d ()
db), (Char
'c', forall d. Dc d => Prism' d ()
dc), (Char
'd', forall d. Dd d => Prism' d ()
dd), (Char
'e', forall d. De d => Prism' d ()
de), (Char
'f', forall d. Df d => Prism' d ()
df)]

-- |
-- >>> 'F' ^? charHEXADECIMALNoZero :: Maybe HEXDigit
-- Just HEXDigitF
--
-- >>> charHEXADECIMALNoZero # HEXDigitF :: Char
-- 'F'
charHEXADECIMALNoZero ::
  HEXADECIMALNoZero d =>
  Prism'
    Char
    d
charHEXADECIMALNoZero :: forall d. HEXADECIMALNoZero d => Prism' Char d
charHEXADECIMALNoZero =
  forall b (p :: * -> * -> *) (f :: * -> *) a.
(Eq b, Choice p, Applicative f) =>
(b, APrism a a () ())
-> [(b, APrism a a () ())] -> p a (f a) -> p b (f b)
associatePrism (Char
'1', forall d. D1 d => Prism' d ()
d1) [(Char
'2', forall d. D2 d => Prism' d ()
d2), (Char
'3', forall d. D3 d => Prism' d ()
d3), (Char
'4', forall d. D4 d => Prism' d ()
d4), (Char
'5', forall d. D5 d => Prism' d ()
d5), (Char
'6', forall d. D6 d => Prism' d ()
d6), (Char
'7', forall d. D7 d => Prism' d ()
d7), (Char
'8', forall d. D8 d => Prism' d ()
d8), (Char
'9', forall d. D9 d => Prism' d ()
d9), (Char
'A', forall d. DA d => Prism' d ()
dA), (Char
'B', forall d. DB d => Prism' d ()
dB), (Char
'C', forall d. DC d => Prism' d ()
dC), (Char
'D', forall d. DD d => Prism' d ()
dD), (Char
'E', forall d. DE d => Prism' d ()
dE), (Char
'F', forall d. DF d => Prism' d ()
dF)]

-- |
-- >>> 'F' ^? charHEXADECIMAL :: Maybe HEXDigit
-- Just HEXDigitF
--
-- >>> charHEXADECIMAL # HEXDigitF :: Char
-- 'F'
charHEXADECIMAL ::
  HEXADECIMAL d =>
  Prism'
    Char
    d
charHEXADECIMAL :: forall d. HEXADECIMAL d => Prism' Char d
charHEXADECIMAL =
  forall b (p :: * -> * -> *) (f :: * -> *) a.
(Eq b, Choice p, Applicative f) =>
(b, APrism a a () ())
-> [(b, APrism a a () ())] -> p a (f a) -> p b (f b)
associatePrism (Char
'0', forall d. D0 d => Prism' d ()
d0) [(Char
'1', forall d. D1 d => Prism' d ()
d1), (Char
'2', forall d. D2 d => Prism' d ()
d2), (Char
'3', forall d. D3 d => Prism' d ()
d3), (Char
'4', forall d. D4 d => Prism' d ()
d4), (Char
'5', forall d. D5 d => Prism' d ()
d5), (Char
'6', forall d. D6 d => Prism' d ()
d6), (Char
'7', forall d. D7 d => Prism' d ()
d7), (Char
'8', forall d. D8 d => Prism' d ()
d8), (Char
'9', forall d. D9 d => Prism' d ()
d9), (Char
'A', forall d. DA d => Prism' d ()
dA), (Char
'B', forall d. DB d => Prism' d ()
dB), (Char
'C', forall d. DC d => Prism' d ()
dC), (Char
'D', forall d. DD d => Prism' d ()
dD), (Char
'E', forall d. DE d => Prism' d ()
dE), (Char
'F', forall d. DF d => Prism' d ()
dF)]

-- |
-- >>> 'f' ^? charHeXaDeCiMaLNoZero :: Maybe HeXDigit
-- Just HeXDigitf
--
-- >>> 'F' ^? charHeXaDeCiMaLNoZero :: Maybe HeXDigit
-- Just HeXDigitF
--
-- >>> charHeXaDeCiMaLNoZero # HeXDigitf :: Char
-- 'f'
--
-- >>> charHeXaDeCiMaLNoZero # HeXDigitF :: Char
-- 'F'
charHeXaDeCiMaLNoZero ::
  HeXaDeCiMaLNoZero d =>
  Prism'
    Char
    d
charHeXaDeCiMaLNoZero :: forall d. HeXaDeCiMaLNoZero d => Prism' Char d
charHeXaDeCiMaLNoZero =
  forall b (p :: * -> * -> *) (f :: * -> *) a.
(Eq b, Choice p, Applicative f) =>
(b, APrism a a () ())
-> [(b, APrism a a () ())] -> p a (f a) -> p b (f b)
associatePrism (Char
'1', forall d. D1 d => Prism' d ()
d1) [(Char
'2', forall d. D2 d => Prism' d ()
d2), (Char
'3', forall d. D3 d => Prism' d ()
d3), (Char
'4', forall d. D4 d => Prism' d ()
d4), (Char
'5', forall d. D5 d => Prism' d ()
d5), (Char
'6', forall d. D6 d => Prism' d ()
d6), (Char
'7', forall d. D7 d => Prism' d ()
d7), (Char
'8', forall d. D8 d => Prism' d ()
d8), (Char
'9', forall d. D9 d => Prism' d ()
d9), (Char
'a', forall d. Da d => Prism' d ()
da), (Char
'b', forall d. Db d => Prism' d ()
db), (Char
'c', forall d. Dc d => Prism' d ()
dc), (Char
'd', forall d. Dd d => Prism' d ()
dd), (Char
'e', forall d. De d => Prism' d ()
de), (Char
'f', forall d. Df d => Prism' d ()
df), (Char
'A', forall d. DA d => Prism' d ()
dA), (Char
'B', forall d. DB d => Prism' d ()
dB), (Char
'C', forall d. DC d => Prism' d ()
dC), (Char
'D', forall d. DD d => Prism' d ()
dD), (Char
'E', forall d. DE d => Prism' d ()
dE), (Char
'F', forall d. DF d => Prism' d ()
dF)]


-- |
-- >>> 'f' ^? charHeXaDeCiMaL :: Maybe HeXDigit
-- Just HeXDigitf
--
-- >>> 'F' ^? charHeXaDeCiMaL :: Maybe HeXDigit
-- Just HeXDigitF
--
-- >>> charHeXaDeCiMaL # HeXDigitf :: Char
-- 'f'
--
-- >>> charHeXaDeCiMaL # HeXDigitF :: Char
-- 'F'
charHeXaDeCiMaL ::
  HeXaDeCiMaL d =>
  Prism'
    Char
    d
charHeXaDeCiMaL :: forall d. HeXaDeCiMaL d => Prism' Char d
charHeXaDeCiMaL =
  forall b (p :: * -> * -> *) (f :: * -> *) a.
(Eq b, Choice p, Applicative f) =>
(b, APrism a a () ())
-> [(b, APrism a a () ())] -> p a (f a) -> p b (f b)
associatePrism (Char
'0', forall d. D0 d => Prism' d ()
d0) [(Char
'1', forall d. D1 d => Prism' d ()
d1), (Char
'2', forall d. D2 d => Prism' d ()
d2), (Char
'3', forall d. D3 d => Prism' d ()
d3), (Char
'4', forall d. D4 d => Prism' d ()
d4), (Char
'5', forall d. D5 d => Prism' d ()
d5), (Char
'6', forall d. D6 d => Prism' d ()
d6), (Char
'7', forall d. D7 d => Prism' d ()
d7), (Char
'8', forall d. D8 d => Prism' d ()
d8), (Char
'9', forall d. D9 d => Prism' d ()
d9), (Char
'a', forall d. Da d => Prism' d ()
da), (Char
'b', forall d. Db d => Prism' d ()
db), (Char
'c', forall d. Dc d => Prism' d ()
dc), (Char
'd', forall d. Dd d => Prism' d ()
dd), (Char
'e', forall d. De d => Prism' d ()
de), (Char
'f', forall d. Df d => Prism' d ()
df), (Char
'A', forall d. DA d => Prism' d ()
dA), (Char
'B', forall d. DB d => Prism' d ()
dB), (Char
'C', forall d. DC d => Prism' d ()
dC), (Char
'D', forall d. DD d => Prism' d ()
dD), (Char
'E', forall d. DE d => Prism' d ()
dE), (Char
'F', forall d. DF d => Prism' d ()
dF)]

---- not exported
associatePrism ::
  (Eq b, Choice p, Applicative f) =>
  (b, APrism a a () ())
  -> [(b, APrism a a () ())]
  -> p a (f a)
  -> p b (f b)
associatePrism :: forall b (p :: * -> * -> *) (f :: * -> *) a.
(Eq b, Choice p, Applicative f) =>
(b, APrism a a () ())
-> [(b, APrism a a () ())] -> p a (f a) -> p b (f b)
associatePrism (b, APrism a a () ())
def [(b, APrism a a () ())]
z =
  forall b s a. (b -> s) -> (s -> Maybe a) -> Prism s s a b
prism'
    (\a
d -> forall a b. (a, b) -> a
fst (forall a. a -> Maybe a -> a
fromMaybe (b, APrism a a () ())
def (forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a
find (\(b
_, APrism a a () ()
w) -> forall s t a b. APrism s t a b -> s -> Bool
is APrism a a () ()
w a
d) [(b, APrism a a () ())]
z)))
    (\b
i -> (\APrism a a () ()
p -> forall s t a b. APrism s t a b -> Prism s t a b
clonePrism APrism a a () ()
p forall t b. AReview t b -> b -> t
# ()) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup b
i ((b, APrism a a () ())
defforall a. a -> [a] -> [a]
:[(b, APrism a a () ())]
z))