Haskell:如何证明(测试)自定义Monad实例是否符合Monad法律?

时间:2018-09-28 14:37:56

标签: haskell monads state-monad

不使用形式推导,如何测试自定义Monad实例是否符合Monad法则?

3 个答案:

答案 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的一种自动测试框架,例如QuickCheckHspec

答案 2 :(得分:0)

这可能有点过头,但是您可以尝试hs-to-coq,它可以将您的hs代码转换为Coq代码,然后您可以证明有关使用Coq (a Proof Assistant)的事情。 / p>

有关使用Coq证明单子律的示例(尽管这不是使用hs-to-coq),请参见: https://github.com/jwiegley/coq-pipes#laws-proven