Reputation: 1832
I have a 'QuasiQuoter' which is useful in source code in Haskell, but also as a standalone application. So, I need to be able to run QuasiQuoter
[myGrammar|someCommand|]
mygrammar 'someCommand'
The first part is easy but the second part might be a little clumsy if solved as calling the compiler with some generated code from the runtime.
I would like to solve a second part of the problem using some nice method in Haskell which doesn't accept only the source code, but accepts QuasyQuoter datatype instead so the code is less clumsy. But I can't find any compilation method like that.
Do you know any? Thanks.
The function takes tuple [(a,b,c,d,e)] and returns a list of the strings with the products.
function = [lsql| {1..5}, r=[ a.* |> (*) ], "Product of a.1 * a.2 * ... * a.5 is &a.r"|]
The command reads from stdin csv with at least 5 numerical columns and returns a list of their products (one per line).
lsql-csv '-, r=[ a.* |> (*) ], "Product of a.1 * a.2 * ... * a.5 is &a.r"'
Upvotes: 1
Views: 159
Reputation: 152682
I think the question is how to parse and process a string in a uniform way between a quasiquoter and some other chunk of code. If this interpretation is right, then you just... do that. For example:
-- 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
Then, in your lsql-csv.hs
, you would write something like
main = do
[s] <- getArgs
case parse command s of
Left err -> die (show err)
Right com -> interpret com
and in your LSql/CSV/QQ.hs
, you would write something like
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
}
Upvotes: 1