{-# OPTIONS_GHC -fwarn-incomplete-patterns #-} {-# OPTIONS_GHC -fwarn-missing-methods #-} {-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} module Data.Numerals.Decimal where import Data.Data import Data.Digits import Data.Typeable import Test.QuickCheck import Test.QuickCheck.Gen data DecimalDigit = Zero | One | Two | Three | Four | Five | Six | Seven | Eight | Nine deriving (Data, Enum, Eq, Ord, Typeable) instance Show DecimalDigit where show = show . fromEnum -- | Takes a DecimalDigit to its Integral form decimal_digit_to_integral :: (Integral n) => DecimalDigit -> n decimal_digit_to_integral digit = case digit of Zero -> 0 One -> 1 Two -> 2 Three -> 3 Four -> 4 Five -> 5 Six -> 6 Seven -> 7 Eight -> 8 Nine -> 9 -- | Takes an Integral digit to a DecimalDigit. This function is partial -- on a set of Integrals. unsafe_integral_digit_to_decimal_digit :: (Integral n) => n -> DecimalDigit unsafe_integral_digit_to_decimal_digit integer = case integer of 0 -> Zero 1 -> One 2 -> Two 3 -> Three 4 -> Four 5 -> Five 6 -> Six 7 -> Seven 8 -> Eight 9 -> Nine integral_to_digits :: (Integral n) => n -> [DecimalDigit] integral_to_digits = (fmap unsafe_integral_digit_to_decimal_digit) . (digits 10) digits_to_integral :: (Integral n) => [DecimalDigit] -> n digits_to_integral = (unDigits 10) . (fmap decimal_digit_to_integral) prop_decimal_digit_round_trip :: [DecimalDigit] -> Bool prop_decimal_digit_round_trip d = (integral_to_digits . digits_to_integral $ d) == d prop_positive_integral_round_trip :: Integral n => n -> Bool prop_positive_integral_round_trip n = (digits_to_integral . integral_to_digits . abs $ n) == abs n