gpt4 book ai didi

haskell - QuasiQuote 带参数

转载 作者:行者123 更新时间:2023-12-04 08:07:32 24 4
gpt4 key购买 nike

我想用 Haskell 写一个引用。需要将 name 参数传递给 gen 函数以生成声明。

quote ::  String -> QuasiQuoter
quote name = QuasiQuoter {
quoteExp = undefined,
quotePat = undefined,
quoteType = undefined,
quoteDec = \jsonStr -> gen name (getValue str)
}

但是,似乎我不能使用这样的报价
[quote "Hello"| from x to y |]

由于 Haskell 不允许引用声明和引用在同一个文件中,这很烦人,我该怎么做才能将参数从外部传递到引用中?

最佳答案

你有两个选择:

  • 切换到使用拼接 $(...) ,
  • 将您的参数编码为输入字符串中的准引号。

  • 使用拼接语法,您的示例将如下所示:
    quote :: String -> String -> Q [Dec]
    quote name jsonStr = gen name (getValue jsonStr)

    并调用它看起来像: $(quote "Hello" "from x to y")
    为了演示选项 2,这里有一个简单的引号,它用一个字符包围一个文字字符串:
    import Language.Haskell.TH (litE, stringL)
    import Language.Haskell.TH.Quote

    surround :: QuasiQuoter
    surround = QuasiQuoter
    { quoteExp = litE . stringL . (\(c:s) -> [c] ++ s ++ [c])
    , quotePat = undefined
    , quoteType = undefined
    , quoteDec = undefined
    }

    -- in another file:
    main = print [surround|_some text|] -- prints "_some text_"

    输入字符串的第一个字符被解释为要使用的括号字符。实际上,我们通过了 Char Char -> QuasiQuoter 类型函数的参数.

    对于更复杂的参数或多个参数,您必须创建自己的语法和解析器来解码它们。

    更新:这是一个稍微复杂一点的例子,调用 [foo| var xyz|]款待 var作为变量名和 xyz作为文字字符串:
    -- [foo| var xyz|]   is translated to:   var ++ "xyz"

    foo :: QuasiQuoter
    foo = QuasiQuoter
    { quoteExp = go
    , quotePat = undefined
    , quoteType = undefined
    , quoteDec = undefined
    }
    where go str = infixE (Just $ varE (mkName var))
    (varE $ mkName "++")
    (Just $ litE (stringL arg1))
    where (var:arg1:_) = words str

    关于haskell - QuasiQuote 带参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27350526/

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