Haskell/SYB
外觀
< Haskell
“拋棄你的樣板程式碼” 方法,在 [1] 中“描述”,是一種允許你的資料結構被所謂的“泛型”函式遍歷的方法:也就是說,函式抽象化了正在建立或修改的特定資料建構函式,同時允許為特定型別新增情況。
例如,如果你想序列化程式碼中的所有結構,但你只想編寫一個在 Data.Data.Data 類(可以用 -XDeriveDataTypeable 推導)的任何例項上操作的序列化函式。
目標是將所有資料轉換為以下格式
data Tag = Con String | Val String
haskell-src-exts 包 將 Haskell 解析為一個相當複雜的語法樹。假設我們想檢查兩個幾乎相同但名稱不同的原始檔是否等價。
首先
import System.Environment
import Language.Haskell.Exts
main = do
-- parse the filenames given by the first two command line arguments,
-- proper error handling is left as an exercise
[ParseOk moduleA, ParseOk moduleB] <- mapM parseFile . take 2 =<< getArgs
putStrLn $ if moduleA == moduleB
then "Your modules are equal"
else "Your modules differ"
從一些測試中可以明顯看出,具有不同名稱的相同檔案不會等於 (==)。但是,為了糾正這一點,而不訴諸大量樣板程式碼,我們可以使用泛型程式設計
描述使用 Data.Generics.Twins.gzip*? 編寫一個函式來查詢差異之處?
或者使用它來編寫一個 geq 的變體,忽略無關緊要的特定情況(SrcLoc 元素)(即 syb 不允許泛型擴充套件……將其與其他庫對比?)。
或者只是解釋這個技巧(效果很好),它在 (==) 之前執行,或者 geq:
everyWhere (mkT $ \ _ -> SrcLoc "" 0 0) :: Data a => a -> a
或者我們能將其發展為編寫比 sim_mira(用於 hs 程式碼)更好的東西,這裡找到:http://dickgrune.com/Programs/similarity_tester/