我目前正在编写一个QuickCheck样式库,并依赖Template Haskell来生成大量测试用例。
我想生成如下代码:
quickCheck (prop_Num_plus_is_associative :: Integer -> Integer -> Integer -> Property)
属性" prop_Monoid_plus_is_associative"有以下类型:
prop_Num_plus_is_associative :: (Eq a, Monoid a, Show a) => a -> a -> a -> Property
这样我就可以使用Monoid
的任何适当实例进行检查。但是,有时,我的程序选择填写的类型" a"不满足上下文。我想通过检查某个实例是否存在来过滤掉这些情况。
但是,当我在reifyInstance
上调用Monoid (Max Integer)
时,它只会向我提供可能匹配的实例列表,即(Bounded a, Ord a) => Monoid (Max a)
,它不执行剩余的工作检查Integer
是Bounded
还是Ord
。是否存在与reifyInstance
类似的函数?
编辑:
这是我暗示的程序:
{-# LANGUAGE TemplateHaskell, QuasiQuotes #-}
import Data.Semigroup
import Language.Haskell.TH
main :: IO ()
main = do
$(do
tMaxInt <- [t| Max Integer |]
runIO . putStrLn . pprint =<< reifyInstances ''Monoid [ tMaxInt ]
[e| return () |] )
输出
instance (GHC.Classes.Ord a_0,
GHC.Enum.Bounded a_0) => GHC.Base.Monoid (Data.Semigroup.Max a_0)
尽管Max Integer
不是Monoid
。