在模板haskell范围之外编译时间代码重写?

gho*_*orn 4 haskell template-haskell

是否有可能创建一个函数,在编译时从模板haskell引号外部重写haskell代码?

例如:

differentiate :: Floating a => (a -> a) -> a -> (a,a)
differentiate = -- what goes here?

f :: Num a => a -> a
f = sin

g :: Num a => a -> (a,a)
g = differentiate f
Run Code Online (Sandbox Code Playgroud)

在编译时它会将g转换为:

g x = (sin x, cos x)
Run Code Online (Sandbox Code Playgroud)

我希望我的"区分"函数能够传递给"f"的AST并让我在编译之前重写它.据我所知,你不能在模板haskell中做到这一点,而不传递函数的完整语法,即"g =区分罪".

谢谢

luq*_*qui 8

你在谈论宏如计划.答案是不.Haskell函数必须是"引用透明",这意味着如果给它两个指称相等的参数,结果必须在表示上相等.即,每个人都 f必须拥有

f (1 + 1) = f 2
Run Code Online (Sandbox Code Playgroud)

如果f是一个宏,这不一定是这样.然而,这个属性对于语言的"纯度"至关重要 - 是什么让Haskell很好地推理和重构.

然而,在Haskell中有大量关于自动区分的工作,其中没有一个需要宏系统 - 抽象建模(以及使类看起来很好的类型类)都是必要的.