haskell - 如何获取 Haskell 代码字符串(连同值)
问题描述
我想同时获取任意 Haskell 代码的字符串和值。例如:
f (1+1) -> (2,"1+1")
我想这样做的原因是因为我正在编写一种编程语言,并且我想提供一个选项来解释代码(用于快速运行,即脚本)或将其编译为 Haskell 代码(用于高效运行时)。因此,对于每个内置函数,我只想提供一次实现。那就是我不想说
plusop = ((+),"(+)")
我有一些想法,包括阅读原始的 haskell 源代码或生成编译器的单独脚本,但如果这个问题是可能的,这些似乎不太优雅。
看起来 QuasiQuotation 可以使这成为可能,但是如果我使用它,我无法弄清楚如何获取表达式的 Haskell 值(我只能获取字符串)。
是否可以?如何做呢?
解决方案
我不确切知道您想做什么,但这里有一个使用 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
并在必要的地方进行更改。或者最简单的可能只是一个后处理步骤,您可以删除以大写字母开头并以 . 结尾的每个单词.
。
推荐阅读
- c++ - 使用模板调度模板化函数的优雅方式
- java - 如何取回存储在 JCEKS 密钥库中的密码?
- vue.js - 无法在 Vue.js 中加载字体
- google-colaboratory - NotFoundError:iris_training.csv
- java - 输入 Java 检查整数中的错误
- c# - 通过正则表达式确定字符串中特定子字符串的顺序
- c++ - 矢量方向计算中的数值误差
- laravel - 使用Vue js上传图片时如何显示图片预览?
- python - Plt.Scatter at seaborn:错误:系列的真值不明确。使用 a.empty、a.bool()、a.item()、a.any() 或 a.all()
- python - IDE 不建议所选对象上可用的方法