-- | A data type with ten nullary constructors and combinators. module Data.Digit ( -- * Data type Digit -- * Constructors , d0 , d1 , d2 , d3 , d4 , d5 , d6 , d7 , d8 , d9 -- * Decisions , is0 , is1 , is2 , is3 , is4 , is5 , is6 , is7 , is8 , is9 -- * Deconstructors , foldDigit , if0 , if1 , if2 , if3 , if4 , if5 , if6 , if7 , if8 , if9 , ifEven , ifOdd ) where -- | A data type with ten nullary constructors. data Digit = D0 | D1 | D2 | D3 | D4 | D5 | D6 | D7 | D8 | D9 deriving (Eq, Ord, Enum, Bounded) 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 _ _ = [] -- | Zero. d0 :: Digit d0 = D0 -- | One. d1 :: Digit d1 = D1 -- | Two. d2 :: Digit d2 = D2 -- | Three. d3 :: Digit d3 = D3 -- | Four. d4 :: Digit d4 = D4 -- | Five. d5 :: Digit d5 = D5 -- | Six. d6 :: Digit d6 = D6 -- | Seven. d7 :: Digit d7 = D7 -- | Eight d8 :: Digit d8 = D8 -- | Nine. d9 :: Digit d9 = D9 -- | Catamorphism for @Digit@. foldDigit :: a -- ^ Zero. -> a -- ^ One. -> a -- ^ Two. -> a -- ^ Three. -> a -- ^ Four. -> a -- ^ Five. -> a -- ^ Six. -> a -- ^ Seven. -> a -- ^ Eight. -> a -- ^ Nine. -> Digit -- ^ The digit to fold. -> a foldDigit d0 _ _ _ _ _ _ _ _ _ D0 = d0 foldDigit _ d1 _ _ _ _ _ _ _ _ D1 = d1 foldDigit _ _ d2 _ _ _ _ _ _ _ D2 = d2 foldDigit _ _ _ d3 _ _ _ _ _ _ D3 = d3 foldDigit _ _ _ _ d4 _ _ _ _ _ D4 = d4 foldDigit _ _ _ _ _ d5 _ _ _ _ D5 = d5 foldDigit _ _ _ _ _ _ d6 _ _ _ D6 = d6 foldDigit _ _ _ _ _ _ _ d7 _ _ D7 = d7 foldDigit _ _ _ _ _ _ _ _ d8 _ D8 = d8 foldDigit _ _ _ _ _ _ _ _ _ d9 D9 = d9 -- | Return the first argument if zero, otherwise the second argument. if0 :: x -> x -> Digit -> x if0 t _ D0 = t if0 _ f _ = f -- | Return the first argument if one, otherwise the second argument. if1 :: x -> x -> Digit -> x if1 t _ D1 = t if1 _ f _ = f -- | Return the first argument if two, otherwise the second argument. if2 :: x -> x -> Digit -> x if2 t _ D2 = t if2 _ f _ = f -- | Return the first argument if three, otherwise the second argument. if3 :: x -> x -> Digit -> x if3 t _ D3 = t if3 _ f _ = f -- | Return the first argument if four, otherwise the second argument. if4 :: x -> x -> Digit -> x if4 t _ D4 = t if4 _ f _ = f -- | Return the first argument if five, otherwise the second argument. if5 :: x -> x -> Digit -> x if5 t _ D5 = t if5 _ f _ = f -- | Return the first argument if six, otherwise the second argument. if6 :: x -> x -> Digit -> x if6 t _ D6 = t if6 _ f _ = f -- | Return the first argument if seven, otherwise the second argument. if7:: x -> x -> Digit -> x if7 t _ D7 = t if7 _ f _ = f -- | Return the first argument if eight, otherwise the second argument. if8 :: x -> x -> Digit -> x if8 t _ D8 = t if8 _ f _ = f -- | Return the first argument if nine, otherwise the second argument. if9 :: x -> x -> Digit -> x if9 t _ D9 = t if9 _ f _ = f -- | Returns whether or not the digit is 0. is0 :: Digit -> Bool is0 = if0 True False -- | Returns whether or not the digit is 1. is1 :: Digit -> Bool is1 = if1 True False -- | Returns whether or not the digit is 2. is2 :: Digit -> Bool is2 = if2 True False -- | Returns whether or not the digit is 3. is3 :: Digit -> Bool is3 = if3 True False -- | Returns whether or not the digit is 4. is4 :: Digit -> Bool is4 = if4 True False -- | Returns whether or not the digit is 5. is5 :: Digit -> Bool is5 = if5 True False -- | Returns whether or not the digit is 6. is6 :: Digit -> Bool is6 = if6 True False -- | Returns whether or not the digit is 7. is7 :: Digit -> Bool is7 = if7 True False -- | Returns whether or not the digit is 8. is8 :: Digit -> Bool is8 = if8 True False -- | Returns whether or not the digit is 9. is9 :: Digit -> Bool is9 = if9 True False -- | Return the first argument if even, otherwise the second argument. ifEven :: x -> x -> Digit -> x ifEven t f = foldDigit t f t f t f t f t f -- | Return the first argument if odd, otherwise the second argument. ifOdd :: x -> x -> Digit -> x ifOdd = flip ifEven