標籤:

template haskell是什麼原理?

haskell在編譯時做了什麼?


給 @祖與占的RTFP補個RTFM,因為現在的Template Haskell API跟原始論文裡面的已經不一樣了:

7.17.Template Haskell &<- 最新版GHC文檔中的Template Haskell指南

template-haskell: Support library for Template Haskell &<- Template Haskell API文檔

效果很簡單,簡而言之就是可以在Haskell的編譯期用代碼生成AST,API封裝在Q Monad裡面。首先,你用Template Haskell API寫一些普通的Haskell代碼,比如genExp :: String -&> Q Exp,代表在Q Monad裡面生成一個Exp,這個Exp也只是API裡面一個普通的datatype,然後你編譯這個module,在其他module裡面import進來。好了,然後在需要有Exp的地方,寫個$(genExp "23333"),好,編譯當前module之前,會首先執行之前定義好的genExp,獲得一個Exp,然後這個Exp插到了這個調用處,然後繼續走普通的編譯流程。允許生成的東西,有Expression/Pattern/Declaration/Type,都是用API裡面的datatype來表示的。

跟Lisp系的宏相比,比較吊的地方有:

  1. 衛生和不衛生宏都支持(newName和mkName,一個在當前scope找identifier,一個生成不能被capture住的乾淨identifier)
  2. Q Monad是Quasi類實例,Quasi類有個方法qRunIO :: Quasi m =&> IO a -&> m a,也就是可以把任意的IO action給lift進來。你寫的Template Haskell代碼可以干「從網上下載一段字元串,當成Haskell源代碼編譯」之類的事情。。
  3. 類型安全。Template Haskell代碼本身類型檢查一次,生成的代碼再類型檢查一次。
  4. QuasiQuote擴展,可以在生成AST的基礎上,加上自定義的parser,也就是直接用新語法擴展Haskell。用Lisp陣營的話叫Reader Macro,不過只有Common Lisp有。。


RTFP (Read The Fucking Paper)

Template metaprogramming for Haskell


推薦閱讀:

Haskell用在工程項目中有什麼優勢?
C++、Haskell、Scala 和 Rust 究竟哪個最複雜?
除回溯外,有哪些比較好用且效率高的解數獨演算法?
GHC API 系列筆記(1):入門篇
函數式編程交流會 2016 粗略

TAG:Haskell |