numeric-qq-0.1.2: library/NumericQQ.hs
module NumericQQ
(
bin,
oct,
hex
)
where
import NumericQQ.Prelude
import Numeric
import Data.Char
import Language.Haskell.TH
import Language.Haskell.TH.Quote
type Base = Int
-- |
-- A binary number quasi-quoter.
--
-- >>> [bin|011|]
-- 3
--
-- >>> [bin|1000001001|]
-- 521
--
bin :: QuasiQuoter
bin = qq 2
-- |
-- An octal number quasi-quoter.
--
-- >>> [oct|7634|]
-- 3996
--
oct :: QuasiQuoter
oct = qq 8
-- |
-- A hexadecimal number quasi-quoter.
--
-- >>> [hex|a23f|]
-- 41535
--
hex :: QuasiQuoter
hex = qq 16
qq :: Base -> QuasiQuoter
qq base = QuasiQuoter {quoteExp = exp} where
exp s =
case parse base s of
Nothing -> fail $ "A string \"" <> s <>
"\" cannot be parsed as a base-" <>
show base <> " number"
Just i -> return $ LitE (IntegerL (fromIntegral i))
parse :: Base -> String -> Maybe Int
parse base string =
case readInt base ((< base) . digitToInt) digitToInt string of
[] -> Nothing
[(r, "")] -> Just r
[(_, _)] -> Nothing
r -> $bug $ "Unexpected parsing result: " <> show r