<p>Hello Haskell Café,</p>
<p>A new version of LeanCheck is out (v0.8.0). LeanCheck is a property
testing library (like QuickCheck) that tests values enumeratively.</p>
<p><em>Whats new?</em> Among several changes, the most notable and significant are:</p>
<ul>
<li>improvements in <a href="https://hackage.haskell.org/package/leancheck/docs/Test-LeanCheck.html">LeanCheck’s Haddock documentation</a>;</li>
<li>removal of a few experimental function enumeration modules;</li>
<li>and improved reporting of functional counter-examples (see below).</li>
</ul>
<p><a href="https://hackage.haskell.org/package/leancheck/changelog">LeanCheck’s changelog</a> provides more details.</p>
<p>Take for example the following higher-order property that takes a
functional argument and states an equivalence between <code>foldl</code> and <code>foldr</code>:</p>
<pre><code>prop_foldlr' :: (Int->Int->Int) -> Int -> [Int] -> Bool
prop_foldlr' f z xs = foldl (flip f) z (reverse xs) == foldr f z xs
</code></pre>
<p>You can check that it is correct by:</p>
<pre><code>> import Test.LeanCheck
> import Test.LeanCheck.Function
> check prop_foldlr'
+++ OK, passed 200 tests.
</code></pre>
<p>Now here is an incorrect version of the above property:</p>
<pre><code>prop_foldlr :: (A -> A -> A) -> A -> [A] -> Bool
prop_foldlr f z xs = foldr f z xs == foldl f z xs
</code></pre>
<p>You can check that it is incorrect by:</p>
<pre><code>> check prop_foldlr
*** Failed! Falsifiable (after 75 tests):
\x _ -> case x of
0 -> 1
_ -> 0
0
[0,0]
</code></pre>
<p>LeanCheck reports the smallest counterexample it finds. The functional
argument is now reported very concisely: a function that returns 1
whenever the first argument is 0 and returns 0 otherwise.</p>
<p>Here’s one last incorrect example property with two functional arguments:</p>
<pre><code>prop_mapFilter :: (Int->Int) -> (Int->Bool) -> [Int] -> Bool
prop_mapFilter f p xs = filter p (map f xs) == map f (filter p xs)
> check prop_mapFilter
*** Failed! Falsifiable (after 36 tests):
\_ -> 0
\x -> case x of
0 -> True
_ -> False
[1]
</code></pre>
<p>The functions <code>map</code> and <code>filter</code> do not commute, the three values above
are a counterexample.</p>
<p>You can find LeanCheck on <a href="https://hackage.haskell.org/package/leancheck">Hackage</a> or <a href="https://github.com/rudymatela/leancheck">GitHub</a>. As usual, you can
install it with:</p>
<pre><code>$ cabal install leancheck
</code></pre>