【问题标题】:How can I get the string of Haskell code (along with the value)如何获取 Haskell 代码字符串(连同值)
【发布时间】:2021-10-18 01:05:17
【问题描述】:

我想获取任意 Haskell 代码的字符串和值。例如:

f (1+1) -> (2,"1+1")

我想这样做的原因是因为我正在编写一种编程语言,并且我想提供一个选项来解释代码(用于快速运行,即脚本)或将其编译为 Haskell 代码(用于高效运行时)。因此,对于每个内置函数,我只想提供一次实现。那就是我不想说

plusop = ((+),"(+)")

我有一些想法,包括阅读原始的 haskell 源代码或生成编译器的单独脚本,但如果这个问题是可能的,这些似乎没有那么优雅。

看起来 QuasiQuotation 可以使这成为可能,但如果我使用它,我不知道如何获取表达式的 Haskell 值(我只能获取字符串)。

有可能吗?怎么办?

【问题讨论】:

  • 您可以使用Hint Haskell interpreter
  • 是的,但我认为这可能会非常低效,因为它会解释所有代码,但是这样操作中的大部分代码仍然被编译。此外,编写解释器比编写编译器更容易(这本质上就是编写编译器——尽管目前这是我所做的,所以可能还不错)。

标签: haskell quasiquotes


【解决方案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代码
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-08-28
  • 2021-02-17
  • 2017-12-20
  • 2018-04-17
  • 1970-01-01
  • 1970-01-01
  • 2023-03-22
相关资源
最近更新 更多