我想实现一个程序来接受任何Haskell表达式并使用前缀表示法重写它。
我希望GHC
本身会转储一些有用的信息(比如解析后添加的括号),但不幸的是,情况似乎并非如此。
$ ghc Example.hs -fforce-recomp -ddump-tc
[1 of 1] Compiling Example ( Example.hs, Example.o )
TYPE SIGNATURES
f :: Maybe ()
TYPE CONSTRUCTORS
COERCION AXIOMS
Dependent modules: []
Dependent packages: [base-4.8.1.0, ghc-prim-0.4.0.0,
integer-gmp-1.0.0.0]
==================== Typechecker ====================
AbsBinds [] []
{Exports: [f <= f_alA
<>]
Exported types: f :: Maybe ()
[LclId, Str=DmdType]
Binds: f_alA = ($) const (GHC.Base.Just) "Foo" GHC.Tuple.()}
哪种现有API最适合此任务?
答案 0 :(得分:3)
哪种现有API最适合此任务?
使用Template Haskell和一个包th-desugar
来模糊模板Haskell。这个想法很简单:将表达式包装在准引用中,将其作为模板haskell,然后再将其渲染为haskell代码。
我在这里重复使用代码以获得其他答案,所以它可能有点混乱:
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE TemplateHaskell #-}
import Control.Monad
import Generics.Deriving.Monoid
import GHC.Generics
import Language.Haskell.TH.Desugar
data T = MkT {str :: String, str' :: String}
deriving (Generic, Show)
main = $([| print $ MkT "a" "b" `mappend` MkT "c" "d" |] >>= dsExp >>= return . expToTH)
instance Monoid T where
mempty = memptydefault
mappend = mappenddefault
通过-ddump-splices
ghc将转储*.dump-splices
文件,显示haskell对源代码所执行的模板:
app\Main.hs:12:10-87: Splicing expression
[| print $ MkT "a" "b" `mappend` MkT "c" "d" |] >>= dsExp
>>= return . expToTH
======>
($) print (mappend (MkT "a" "b") (MkT "c" "d"))