我正在读“Haskell Book”的monoid区段,作者使用QuickCheck检查僧侣法律。我自己写了一些东西后,我有这样的代码:如何定义没有泛型类型参数的泛型函数?
module Main where
import Data.Monoid
import Test.QuickCheck
monoidAssoc :: (Eq m, Monoid m) => m -> m -> m -> Bool
monoidAssoc a b c = ((a <> b) <> c) == (a <> (b <> c))
monoidLeftId :: (Eq m, Monoid m) => m -> Bool
monoidLeftId a = (mempty <> a) == a
monoidRightId :: (Eq m, Monoid m) => m -> Bool
monoidRightId a = (a <> mempty) == a
type AssocCheck a = a -> a -> a -> Bool
type IdCheck a = a -> Bool
main :: IO()
main = do
quickCheck (monoidAssoc :: AssocCheck (Maybe String))
quickCheck (monoidLeftId :: IdCheck (Maybe String))
quickCheck (monoidRightId :: IdCheck (Maybe String))
quickCheck (monoidAssoc :: AssocCheck [String])
quickCheck (monoidLeftId :: IdCheck [String])
quickCheck (monoidRightId :: IdCheck [String])
正如你可以看到main
功能有两个,我想,以减少这样的事情几乎相同的块:
checkMonoid :: (Eq m, Monoid m) => m -> IO()
checkMonoid = do
quickCheck (monoidAssoc :: AssocCheck m)
quickCheck (monoidLeftId :: IdCheck m)
quickCheck (monoidRightId :: IdCheck m)
main :: IO()
main = do
checkMonoid :: Maybe String -> IO()
checkMonoid :: [String] -> IO()
但这显然是行不通的。我在这里想要以某种方式将类型传递给checkMonoid
函数,因此quickCheck
函数将知道必须生成的数据是什么arbitrary
。