module Data.Digit.Digit
(
Digit
, foldDigit
, digit
, digitC
, digitQ
) where
import Prelude(Show(..), Read(..), Eq, Enum(..), Maybe(..), Bounded, Ord, Int, Char, (.), const, maybe, error)
import Data.Digit.D0
import Data.Digit.D1
import Data.Digit.D2
import Data.Digit.D3
import Data.Digit.D4
import Data.Digit.D5
import Data.Digit.D6
import Data.Digit.D7
import Data.Digit.D8
import Data.Digit.D9
import Control.Lens
import Data.Data (Data)
import Data.Typeable (Typeable)
import Language.Haskell.TH
import Language.Haskell.TH.Quote
data Digit =
D0
| D1
| D2
| D3
| D4
| D5
| D6
| D7
| D8
| D9
deriving (Eq, Ord, Enum, Bounded, Data, Typeable)
foldDigit ::
a
-> a
-> a
-> a
-> a
-> a
-> a
-> a
-> a
-> a
-> Digit
-> a
foldDigit x0 _ _ _ _ _ _ _ _ _ D0 =
x0
foldDigit _ x1 _ _ _ _ _ _ _ _ D1 =
x1
foldDigit _ _ x2 _ _ _ _ _ _ _ D2 =
x2
foldDigit _ _ _ x3 _ _ _ _ _ _ D3 =
x3
foldDigit _ _ _ _ x4 _ _ _ _ _ D4 =
x4
foldDigit _ _ _ _ _ x5 _ _ _ _ D5 =
x5
foldDigit _ _ _ _ _ _ x6 _ _ _ D6 =
x6
foldDigit _ _ _ _ _ _ _ x7 _ _ D7 =
x7
foldDigit _ _ _ _ _ _ _ _ x8 _ D8 =
x8
foldDigit _ _ _ _ _ _ _ _ _ x9 D9 =
x9
instance D0 Digit where
d0 =
D0
instance D1 Digit where
d1 =
D1
instance D2 Digit where
d2 =
D2
instance D3 Digit where
d3 =
D3
instance D4 Digit where
d4 =
D4
instance D5 Digit where
d5 =
D5
instance D6 Digit where
d6 =
D6
instance D7 Digit where
d7 =
D7
instance D8 Digit where
d8 =
D8
instance D9 Digit where
d9 =
D9
digit ::
Prism' Int Digit
digit =
prism'
fromEnum
(\n -> case n of 0 -> Just D0
1 -> Just D1
2 -> Just D2
3 -> Just D3
4 -> Just D4
5 -> Just D5
6 -> Just D6
7 -> Just D7
8 -> Just D8
9 -> Just D9
_ -> Nothing)
digitC ::
Prism' Char Digit
digitC =
prism'
(\d -> case d of D0 -> '0'
D1 -> '1'
D2 -> '2'
D3 -> '3'
D4 -> '4'
D5 -> '5'
D6 -> '6'
D7 -> '7'
D8 -> '8'
D9 -> '9')
(\n -> case n of '0' -> Just D0
'1' -> Just D1
'2' -> Just D2
'3' -> Just D3
'4' -> Just D4
'5' -> Just D5
'6' -> Just D6
'7' -> Just D7
'8' -> Just D8
'9' -> Just D9
_ -> Nothing)
instance Show Digit where
show = show . fromEnum
instance Read Digit where
readsPrec _ ('0':t) =
[(D0, t)]
readsPrec _ ('1':t) =
[(D1, t)]
readsPrec _ ('2':t) =
[(D2, t)]
readsPrec _ ('3':t) =
[(D3, t)]
readsPrec _ ('4':t) =
[(D4, t)]
readsPrec _ ('5':t) =
[(D5, t)]
readsPrec _ ('6':t) =
[(D6, t)]
readsPrec _ ('7':t) =
[(D7, t)]
readsPrec _ ('8':t) =
[(D8, t)]
readsPrec _ ('9':t) =
[(D9, t)]
readsPrec _ _ =
[]
digitQ :: QuasiQuoter
digitQ = QuasiQuoter {
quoteExp = dexp
, quotePat = dpat
, quoteType = error "not quotable"
, quoteDec = error "not quotable"
}
dexp :: [Char] -> ExpQ
dexp ('$':vn) = varE (mkName vn)
dexp (d:[]) = maybe (error "not a digit") (dataToExpQ (const Nothing)) (d ^? digitC)
dexp _ = error "not a digit"
dpat :: [Char] -> PatQ
dpat ('$':vn) = varP (mkName vn)
dpat (d:[]) = maybe (error "not a digit") (dataToPatQ (const Nothing)) (d ^? digitC)
dpat _ = error "not a digit"