前言 Link to heading

Haskell 提供了多种 meta program 的方案。就突然有点好奇,为什么会有这么多,实际使 用的话以合优先。就随便思考了一下。

思考 Link to heading

TH 的特性在于编译期代码生成。类似于 rust 的 macro 与 lisp 的 macro。提供了输入的 语法解析,然后再变换生成所需要的代码。理论上来说,所有有规则的生成都可以用 TH 来 完成。但在一部分场景下这样的做法可能过于麻烦。 最直接的使用就是基于给定的参数来生成相应的代码。即输入直接影响输出的代码。

Generics,典型的应用就是 aeson 这样的序列化库。 我认为主要目的是观测不同结构的值进行变换,得到相似结构的值。 相较于 TH 中去自己解析、创建相应的变换,Generics 可以直接通过输入对象的结构,来 完成我们所想需要的工作。它更加针对的输入的结构,且输出的处理是跟随这一结构的。

Typeable 主要用于处理类型。如 Servant 库就通过类型标记来完成一些语义上的说明与代 码生成。这里又可以分为运行期的与静态可确定的信息。 类型本身在这里也可以比较判断,从而提供了更加灵活的运行期逻辑控制。 相较于 TH,主要优点就是可以方便的拿运行期的值,与类型(静态的)相比较判断,从而 进行分支。而分支的目标可能是由用户提供扩展,而非 TH 那样直接生成的特定代码(当 然,TH 也能做到接受一些代码,给你包起来)。 它更加注重的是运行期数据对应的行为,参数只是决定了计算的类别,而不决定具体的行为。

不论何种方式,TH 的方法基本可以处理所有问题,但生成代码也就意味着要处理的事情会 更多。而 Generics 与 Typeable 则是针对一些不同场景而做出的特例。