如何获取 Haskell 代码字符串(连同值)
Posted
技术标签:
【中文标题】如何获取 Haskell 代码字符串(连同值)【英文标题】:How can I get the string of Haskell code (along with the value) 【发布时间】:2021-10-18 01:05:17 【问题描述】:我想获取任意 Haskell 代码的字符串和值。例如:
f (1+1) -> (2,"1+1")
我想这样做的原因是因为我正在编写一种编程语言,并且我想提供一个选项来解释代码(用于快速运行,即脚本)或将其编译为 Haskell 代码(用于高效运行时)。因此,对于每个内置函数,我只想提供一次实现。那就是我不想说
plusop = ((+),"(+)")
我有一些想法,包括阅读原始的 haskell 源代码或生成编译器的单独脚本,但如果这个问题是可能的,这些似乎没有那么优雅。
看起来 QuasiQuotation 可以使这成为可能,但如果我使用它,我不知道如何获取表达式的 Haskell 值(我只能获取字符串)。
有可能吗?怎么办?
【问题讨论】:
您可以使用Hint Haskell interpreter 是的,但我认为这可能会非常低效,因为它会解释所有代码,但是这样操作中的大部分代码仍然被编译。此外,编写解释器比编写编译器更容易(这本质上就是编写编译器——尽管目前这是我所做的,所以可能还不错)。 【参考方案1】:我不知道你到底想做什么,但这里有一个使用 Template Haskell 做与你的例子类似的事情的例子:
-- TH.hs
-# LANGUAGE TemplateHaskell #-
module TH where
import Language.Haskell.TH.Syntax
import Language.Haskell.TH.Ppr
showAndRun :: Q Exp -> Q Exp
showAndRun m = do
x <- m
let s = pprint x
[| ($m, s) |]
-- Main.hs
-# LANGUAGE TemplateHaskell #-
import TH
main :: IO ()
main = print $(showAndRun [| 1 + 1 |])
$ runhaskell Main.hs
(2,"1 GHC.Num.+ 1")
我不知道如何在没有限定 GHC.Num
前缀的情况下漂亮地打印表达式。您可以尝试复制Language.Haskell.TH.Ppr
的实现并在必要的地方进行更改。或者最简单的可能只是一个后处理步骤,您可以删除以大写字母开头并以.
结尾的每个单词。
【讨论】:
谢谢,这就是我想做的! GHC 编号添加在那里很好,因为那仍然是无需修改即可编译的haskell代码以上是关于如何获取 Haskell 代码字符串(连同值)的主要内容,如果未能解决你的问题,请参考以下文章
Haskell:如何将 IO 输入字符串解析为 Float(或 Int 或其他)?
如何在现有的 Haskell 代码中从 String 转到 Data.ByteString.Lazy?