1

我有一个“QuasiQuoter”,它在 Haskell 的源代码中很有用,但也可以作为一个独立的应用程序。所以,我需要能够运行 QuasiQuoter

  1. 在 Haskell 的编译期间 -[myGrammar|someCommand|]
  2. 在 shell 的运行时(运行时编译)中 -mygrammar 'someCommand'

第一部分很简单,但如果解决为使用运行时生成的一些代码调用编译器来解决,第二部分可能会有点笨拙。

我想在 Haskell 中使用一些不错的方法来解决问题的第二部分,它不只接受源代码,而是接受 QuasyQuoter 数据类型,因此代码不那么笨拙。但我找不到任何这样的编译方法。

你知道任何?谢谢。

使用示例

哈斯克尔

该函数采用元组 [(a,b,c,d,e)] 并返回包含产品的字符串列表。

function = [lsql| {1..5}, r=[ a.* |> (*) ], "Product of a.1 * a.2 * ... * a.5 is &a.r"|]

重击

该命令从 stdin csv 中读取至少 5 个数字列,并返回其产品列表(每行一个)。

lsql-csv '-, r=[ a.* |> (*) ], "Product of a.1 * a.2 * ... * a.5 is &a.r"'
4

1 回答 1

1

认为问题是如何在准引用器和其他代码块之间以统一的方式解析和处理字符串。如果这个解释是正确的,那么你就……这样做。例如:

-- implementation of these is left to the reader, but can use standard Haskell
-- programming techniques and libraries, like parsec and ADTs and stuff
command :: Parser Command
interpret :: Command -> IO ()
jit :: Command -> Exp -- or Q Exp

然后,在你的lsql-csv.hs,你会写类似

main = do
    [s] <- getArgs
    case parse command s of
        Left err -> die (show err)
        Right com -> interpret com

在你的 中LSql/CSV/QQ.hs,你会写类似

lsql = QuasiQuoter { quoteExp = \s -> case parse command s of
    Left err -> qReport True (show err) >> fail ""
    Right com -> return (jit com) -- or just jit com if that's already a Q Exp
    }
于 2022-02-07T15:24:46.487 回答