module Data.Type.Index.Quote where
import Data.Type.Index
import Language.Haskell.TH
import Language.Haskell.TH.Lib
import Language.Haskell.TH.Quote
import Text.Read (readMaybe)
import Control.Monad
ix :: QuasiQuoter
ix = QuasiQuoter
{ quoteExp = parseIxExp
, quotePat = parseIxPat
, quoteType = error "ix: quoteType not defined"
, quoteDec = error "ix: quoteDec not defined"
}
parseIxExp :: String -> Q Exp
parseIxExp s = maybe (fail $ "ix: couldn't parse Int: " ++ show s)
(notNeg >=> go)
$ readMaybe s
where
notNeg :: Int -> Q Int
notNeg n
| n < 0 = fail $ "ix: negative index: " ++ show n
| True = return n
go :: Int -> Q Exp
go = \case
0 -> [| IZ |]
n -> [| IS $(go $ n1) |]
parseIxPat :: String -> Q Pat
parseIxPat s = maybe (fail $ "ix: couldn't parse Int: " ++ show s)
(notNeg >=> go)
$ readMaybe s
where
notNeg :: Int -> Q Int
notNeg n
| n < 0 = fail $ "ix: negative index: " ++ show n
| True = return n
go :: Int -> Q Pat
go = \case
0 -> [p| IZ |]
n -> [p| IS $(go $ n1) |]