I want to make an expression such that I have a compiletime error or a URI.
[uri|http://stackoverflow.com|]
should compile, but
[uri|foo:/bar:\|]
should not.
I've come across QuasiQuotes, which are apparently for this kind of problem. However, I can't seem to create the Q Exp
from the parsed URI
.
import Language.Haskell.TH.Quote
import Language.Haskell.TH.Syntax
import Language.Haskell.TH
import URI.ByteString
import Data.ByteString.Char8
uri = QuasiQuoter { quoteExp = \s ->
let
uri = either (\err -> error $ show err) id (parseURI laxURIParserOptions (pack s))
in
[| uri |]
}
Doesn't compile, because it wants a Lift
instance for URI
. However, I'm not sure how to create one, due to the GADT nature.
deriving instance Lift (URIRef a)
Complains about no Lift ByteString
, but I have no idea to write one. Another way would be the Data URI
, but that fails with
85 1 error • Couldn't match type ‘a’ with ‘Absolute’
‘a’ is a rigid type variable bound by
the instance declaration at uri-bytestring/src/URI/ByteString/Types.hs:85:1
Expected type: c (URIRef a)
Actual type: c (URIRef Absolute)
• In the expression: k (k (k (k (k (z URI)))))
In a case alternative:
ghc-prim-0.5.0.0:GHC.Types.I# 1# -> k (k (k (k (k (z URI)))))
In the expression:
case constrIndex c of {
ghc-prim-0.5.0.0:GHC.Types.I# 1# -> k (k (k (k (k (z URI)))))
_ -> k (k (k (k (z RelativeRef)))) }
When typechecking the code for ‘gunfold’
in a derived instance for ‘Data (URIRef a)’:
To see the code I am typechecking, use -ddump-deriv
• Relevant bindings include
gunfold :: (forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (URIRef a)
(bound at uri-bytestring/src/URI/ByteString/Types.hs:85:1) (haskell-stack-ghc)
I'd prefer to use Generics
, but I'm not sure how to use them with the QQ APIs.