{-# LANGUAGE Safe #-} {-| Module : Data.Char.Number.Duodecimal Description : A module used to render duodecimal numbers. Maintainer : hapytexeu+gh@gmail.com Stability : experimental Portability : POSIX The <https://www.unicode.org/charts/PDF/U2150.pdf 2150 unicode block> contains two characters for duodecimal numbers: numbers with base 12. In order to represent digits for 10 and 11, unicode has two codepoints: @TURNED DIGIT TWO@, and @TURNED DIGIT THREE@. This module makes it more convenient to convert an 'Integral' number to these digits, as well as converting a number to its duodecimal representation. -} module Data.Char.Number.Duodecimal ( -- * Characters used for duodecimal numbers char10, char11 -- * Convert values to digits , duodecimalDigit, duodecimalDigit' -- * Convert value to a sequence of digits , duodecimalNumber, duodecimalNumber' ) where import Data.Bits((.|.)) import Data.Char(chr) import Data.Char.Core(PlusStyle, positionalNumberSystem) import Data.Default(def) import Data.Text(Text) -- | The character used to denote 10: @ↀ@. char10 :: Char -- ^ A character used in duodecimal numbers to denote 10. char10 = '\x2180' -- | The character used to denote 11: @ↁ@. char11 :: Char -- ^ A character used in duodecimal numbers to denote 11. char11 = '\x2181' _duodecimalDigit :: Int -> Char _duodecimalDigit n | n < 10 = chr (0x30 .|. n) | otherwise = chr (0x2180 .|. n) -- | Convert the given 'Integral' number to its unicode character. In case the -- value is less than @0@, or greater than @11@, the behavior is unspecified. duodecimalDigit' :: Integral i => i -- ^ The given number to convert. -> Char -- ^ A unicode character that represents this digit. duodecimalDigit' = _duodecimalDigit . fromIntegral -- | Convert the given 'Integral' number to its unicode character wrapped in a -- 'Just' data constructor. In case the value is less than @0@ or greater than -- @11@, 'Nothing' is returned. duodecimalDigit :: Integral i => i -> Maybe Char duodecimalDigit n | n >= 0 && n < 12 = Just (duodecimalDigit' n) | otherwise = Nothing -- | Convert the given 'Integral' number to a 'Text' object that contains -- a sequence of duodecimal digits that represent that number. The given -- 'PlusStyle' specifies if the number is prefixed with @+@ if it is positive. duodecimalNumber :: Integral i => PlusStyle -- ^ The given 'PlusStyle' to use. -> i -- ^ The given number to convert. -> Text -- ^ A string of unicode characters representing the value in duodecimal notation. duodecimalNumber = positionalNumberSystem 12 _duodecimalDigit '+' '-' -- | Convert the given 'Integral' number to a 'Text' object that contains -- sequence of duodecimal digits that represent that number. duodecimalNumber' :: Integral i => i -- ^ The given number to convert. -> Text -- ^ A string of unicode characters representing the value in duodecimal notation. duodecimalNumber' = duodecimalNumber def