gpt4 book ai didi

haskell - 编译时检查的 URI

转载 作者:行者123 更新时间:2023-12-04 13:57:20 26 4
gpt4 key购买 nike

我想制作一个表达式,使我有编译时错误或 URI .

[uri|http://stackoverflow.com|]

应该编译,但是
[uri|foo:/bar:\|]

不应该。

我遇到了 QuasiQuotes,这显然是针对这类问题的。但是,我似乎无法创建 Q Exp来自解析的 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 |]
}

不编译,因为它需要 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 一起使用。

最佳答案

你快到了 - Lift Bytestring th-lift-instances 中提供了您要查找的实例包裹。

import Instances.TH.Lift

当然,您也可以只复制相关实例而不是产生依赖关系。
-- ByteString
instance Lift ByteString where
lift b = [| pack $(lift $ unpack b) |]

然后,使用 DeriveLift , StandaloneDeriving , GADTs , 和 TemplateHaskell开启,可以创建孤儿 Lift所有类型的实例 URIRef取决于(及物)依赖。
deriving instance Lift (URIRef a)
deriving instance Lift Authority
deriving instance Lift UserInfo
deriving instance Lift Query
deriving instance Lift Host
deriving instance Lift Port
deriving instance Lift Scheme

通过此添加,您的代码现在可以编译。在 GHCi,我得到以下交互,确认一切正常。
ghci> :set -XQuasiQuotes
ghci> [uri|http://stackoverflow.com|]
URI {uriScheme = Scheme {schemeBS = "http"}, uriAuthority = Just (Authority {authorityUserInfo = Nothing, authorityHost = Host {hostBS = "stackoverflow.com"}, authorityPort = Nothing}), uriPath = "", uriQuery = Query {queryPairs = []}, uriFragment = Nothing}
ghci> [uri|foo:/bar:\|]

<interactive>:3:1: error:
• Exception when trying to run compile-time code:
MalformedPath
CallStack (from HasCallStack):
error, called at uri.hs:25:47 in main:Main
Code: quoteExp uri "foo:/bar:\\"
• In the quasi-quotation: [uri|foo:/bar:\|]
ghci>

编辑

只是注意到我从未回答过你问题的最后一部分。

I'd prefer to use Generics, but I'm not sure how to use them with the QQ APIs.



那是不可能的——通用编程不会让你在编译时执行任意的验证代码。你真的需要 TemplateHaskell为了这。充其量你可以在 TemplateHaskell 中使用它们。生成的代码,但这将是不必要的(那里没有通用的东西)。

关于haskell - 编译时检查的 URI,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42126267/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com