不使用形式推导,如何测试自定义Monad
实例是否符合Monad法则?
答案 0 :(得分:6)
FWIW,这是我最近写的一组QuickCheck属性,用于测试Monad定律以从其F-代数派生的Maybe实现:
testProperty "Monad left identity law" $ do
a :: String <- arbitrary
k :: String -> MaybeFix Integer <- (fromMaybe .) <$> arbitrary
let left = return a >>= k
let right = k a
return $ left == right
,
testProperty "Monad right identity law" $ do
m :: MaybeFix Integer <- fromMaybe <$> arbitrary
let left = m >>= return
let right = m
return $ left == right
,
testProperty "Monad associativity law" $ do
m :: MaybeFix String <- fromMaybe <$> arbitrary
k :: String -> MaybeFix Integer <- (fromMaybe .) <$> arbitrary
h :: Integer -> MaybeFix Ordering <- (fromMaybe .) <$> arbitrary
let left = m >>= (\x -> k x >>= h)
let right = (m >>= k) >>= h
return $ left == right
答案 1 :(得分:4)
我想你知道摩纳德定律是什么,但是为了完整起见,我会link them。
由于您明确提到测试而不是正式证明,因此可以使用Haskell的一种自动测试框架,例如QuickCheck或Hspec。
答案 2 :(得分:0)
这可能有点过头,但是您可以尝试hs-to-coq,它可以将您的hs代码转换为Coq代码,然后您可以证明有关使用Coq (a Proof Assistant)的事情。 / p>
有关使用Coq证明单子律的示例(尽管这不是使用hs-to-coq),请参见: https://github.com/jwiegley/coq-pipes#laws-proven