dav*_*420 5 haskell template-haskell
我有一个玩具程序:
$ cat a.hs
main = putStrLn "Toy example"
$ runghc a.hs
Toy example
Run Code Online (Sandbox Code Playgroud)
让我们向其中添加一些模板 Haskell:
$ cat b.hs
{-# LANGUAGE TemplateHaskell #-}
id [d|
main = putStrLn "Toy example"
|]
$ runghc b.hs
b.hs:3:0: parse error (possibly incorrect indentation)
Run Code Online (Sandbox Code Playgroud)
那么,让我们修复缩进:
$ cat c.hs
{-# LANGUAGE TemplateHaskell #-}
id [d|
main = putStrLn "Toy example"
|]
$ runghc c.hs
Toy example
Run Code Online (Sandbox Code Playgroud)
一个空格就足够了,但我必须缩进两个尾随行。
我可以避免缩进我的大部分模块吗?(我的 Real Modules 不止一行代码。)(而且没有使用{ ; ; }符号?)
我确实希望在引用中捕获所有模块声明 - 在正常代码中我可以替换(...)为$ ...,是否有一些等效的[d|...|]可以让我避免使用右括号和缩进?
或者是有一些方法模块一个可以说,任何模块的顶层声明乙是一个被导入由函数自动处理一个出口?
笔记:
id它更复杂——它扫描变量名的声明prop_,并构建一个包含它们的测试套件。是否有其他一些纯粹的 Haskell 方法可以代替我执行此操作,而无需直接修改源文件?b.hs:3:1——但行为在其他方面是相同的。[我的程序] 扫描以 prop_ 开头的变量名称的声明,并构建包含它们的测试套件。有没有其他一些纯粹的 Haskell 方法可以代替,而不直接修改源文件?
就在这里!使用包language-haskell-extract。
{-# LANGUAGE TemplateHaskell #-}
import Language.Haskell.Extract
import Test.QuickCheck
prop_foo xs = reverse (reverse xs) == (xs :: [Int])
prop_bar = 2 + 2 == 4
properties = $(functionExtractorMap "^prop_"
[|\name prop -> putStrLn name >> quickCheck prop|])
main = sequence_ properties
Run Code Online (Sandbox Code Playgroud)
运行这个,我们得到:
prop_foo
+++ OK, passed 100 tests.
prop_bar
+++ OK, passed 100 tests.
Run Code Online (Sandbox Code Playgroud)
然而,在你重新发明轮子之前,我还建议你看一下这个test-framework-th包,它几乎完全做到了这一点,而且还支持 HUnit 并有一个很好的测试运行器(带有颜色!)。
{-# LANGUAGE TemplateHaskell #-}
import Test.Framework.Providers.HUnit
import Test.Framework.Providers.QuickCheck2
import Test.Framework.TH
import Test.HUnit
import Test.QuickCheck
prop_bar = 1+1 == 2
case_foo = 2+2 @?= 4
main = $(defaultMainGenerator)
Run Code Online (Sandbox Code Playgroud)
输出:
Main:
bar: [OK, passed 100 tests]
foo: [OK]
Properties Test Cases Total
Passed 1 1 2
Failed 0 0 0
Total 1 1 2
Run Code Online (Sandbox Code Playgroud)
testGroupGenerator如果您想组合多个文件中的测试,还有一个很有用。