d10-1: src/D10/Char/Unsafe.hs
{-# language Unsafe, GeneralizedNewtypeDeriving #-}
module D10.Char.Unsafe (D10 (D10_Unsafe)) where
import qualified D10.Predicate as Predicate
import Data.Char (chr, ord)
import Data.Monoid (Endo (..))
---------------------------------------------------
-- | A 'Char' value between @'0'@ and @'9'@
newtype D10 =
D10_Unsafe Char
-- ^ The constructor's name include the word "unsafe" as a reminder
-- that you should generally avoid using it directly, because it
-- allows constructing invalid 'D10' values.
deriving (Eq, Ord)
---------------------------------------------------
instance Bounded D10
where
minBound = D10_Unsafe '0'
maxBound = D10_Unsafe '9'
---------------------------------------------------
instance Enum D10
where
fromEnum :: D10 -> Int
fromEnum (D10_Unsafe x) = ord x - ord '0'
toEnum :: Int -> D10
toEnum x | Predicate.isD10Int x = D10_Unsafe (chr (x + ord '0'))
| otherwise = error "d10 must be between 0 and 9"
enumFrom :: D10 -> [D10]
enumFrom x = enumFromTo x maxBound
enumFromThen :: D10 -> D10 -> [D10]
enumFromThen x y = enumFromThenTo x y bound
where
bound | fromEnum y >= fromEnum x = maxBound
| otherwise = minBound
succ :: D10 -> D10
succ (D10_Unsafe '9') = error "D10 overflow"
succ (D10_Unsafe x) = D10_Unsafe (succ x)
pred :: D10 -> D10
pred (D10_Unsafe '0') = error "D10 underflow"
pred (D10_Unsafe x) = D10_Unsafe (pred x)
---------------------------------------------------
instance Show D10 where
showsPrec _ x = showString "[d10|" . showsChar x . showString "|]"
showList xs = showString "[d10list|" . showsStr xs . showString "|]"
showsChar :: D10 -> ShowS
showsChar (D10_Unsafe x) = showChar x
showsStr :: [D10] -> ShowS
showsStr = appEndo . foldMap (Endo . showsChar)