gpt4 book ai didi

haskell - 如何在 Haskell 中编写模式准引用器?

转载 作者:行者123 更新时间:2023-12-02 18:06:31 25 4
gpt4 key购买 nike

我使用准引用符在编译时创建智能构造的数据类型。这看起来像:

import qualified Data.Text as T
import Language.Haskell.TH.Quote (QuasiQuoter(..))
import Language.Haskell.TH (Q, Exp, Pat(..), Lit(..))
import Language.Haskell.TH.Syntax (Lift(..))
import qualified Language.Haskell.TH.Syntax as TH
import Instances.TH.Lift () -- th-lift-instances package

newtype NonEmptyText = NonEmptyText Text

textIsWhitespace :: Text -> Bool
textIsWhitespace = T.all (== ' ')

mkNonEmptyText :: Text -> Maybe NonEmptyText
mkNonEmptyText t = if textIsWhitespace t then Nothing else (Just (NonEmptyText t))

compileNonEmptyText :: QuasiQuoter
compileNonEmptyText = QuasiQuoter
{ quoteExp = compileNonEmptyText'
, quotePat = error "NonEmptyText is not supported as a pattern"
, quoteDec = error "NonEmptyText is not supported at top-level"
, quoteType = error "NonEmptyText is not supported as a type"
}
where
compileNonEmptyText' :: String -> Q Exp
compileNonEmptyText' s = case mkNonEmptyText (pack s) of
Nothing -> fail $ "Invalid NonEmptyText: " ++ s
Just txt -> [| txt |]

(如果需要,我可以提供一个独立的工作示例 - 我只是从更大的代码库中提取了这个示例)

本质上,只需为我的新类型派生 Lift ,我就可以将数据类型放入准引用表达式 [| txt |] 来实现 quoteExp

但是我在使用 quotePat 时遇到了麻烦。如果我这样做,例如:

Just txt -> [p| txt |]

然后我收到一条警告,指出第一个 txt 未使用,第二个文本遮盖了第一个文本。我非常确定该模式只是创建一个新名称 txt 而不是像表达式准引用者那样在范围内 txt 中进行拼接,因为当我这样做时:

f :: NonEmptyText -> Bool
f [compileNonEmptyText|test|] = True
f _ = False

一切都与第一个陈述相符。

最佳答案

好吧,我想我已经明白了。从基本字符串 s 开始,我可以将其包装在 StringLLitP 中以获得文字字符串,这是因为 TextIsString 实例将成为 Text。从那里我需要使用 ConP 应用 NonEmptyText 构造函数:

compileNonEmptyTextPattern' :: String -> Q TH.Pat
compileNonEmptyTextPattern' s = case mkNonEmptyText (pack s) of
Nothing -> fail $ "Invalid NonEmptyText: " ++ s
Just (NonEmptyText txt) -> pure $ ConP 'NonEmptyText [(LitP (StringL (T.unpack txt)))]

不幸的是,这比表达式版本冗长得多!我想知道 Q Pat 是否有一个类型类,就像 LiftQ Exp 的类型类?

关于haskell - 如何在 Haskell 中编写模式准引用器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54798284/

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