{-# LANGUAGE LambdaCase, OverloadedStrings #-}
{-# LANGUAGE GeneralizedNewtypeDeriving, DeriveGeneric, DeriveDataTypeable #-}
module Digit where
import Prelude.Spiros

import Data.Word (Word8)
import GHC.Exts (IsString)

newtype Digit = Digit Word8       -- TODO modular arithmetic: type Digit = Natural `Mod` 10
 deriving (Show,Read,Eq,Ord,Generic,Data,NFData,Hashable)

instance Bounded Digit where
 minBound = Digit 0
 maxBound = Digit 9

instance Enum Digit where
 toEnum i
  | minBound <= i && i <= maxBound = Digit (toEnum i)
  | otherwise                      = error ("Digit.toEnum: " ++ show i ++ " is not a single-digit integer")
 fromEnum (Digit i) = fromEnum i

parseDigit :: (IsString s, Eq s) => s -> Maybe Digit
parseDigit = \case
 "0" -> Just $ Digit 0
 "1" -> Just $ Digit 1
 "2" -> Just $ Digit 2
 "3" -> Just $ Digit 3
 "4" -> Just $ Digit 4
 "5" -> Just $ Digit 5
 "6" -> Just $ Digit 6
 "7" -> Just $ Digit 7
 "8" -> Just $ Digit 8
 "9" -> Just $ Digit 9
 _   -> Nothing

isDigit :: (Integral a) => a -> Maybe Digit
isDigit i = if 0 >= i && i <= 9 then Just (Digit (fromIntegral i)) else Nothing