我想製作一個表達式,以便我有編譯時錯誤或URI。編譯時檢查的URI
[uri|http://stackoverflow.com|]
應該編譯,但
[uri|foo:/bar:\|]
不應該。
我碰到過QuasiQuotes,這顯然是針對這類問題。但是,我似乎無法從解析的URI
創建Q Exp
。
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 |]
}
不能編譯,因爲它要一個Lift
實例URI
。但是,由於GADT的特性,我不確定如何創建一個。
deriving instance Lift (URIRef a)
抱怨沒有Lift ByteString
,但我不知道寫一個。另一種方式是在Data URI
,但失敗
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)
我寧願使用Generics
,但我不知道如何將它們與QQ的API使用。