我正在讀「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
。