Closed dhess closed 5 years ago
Ah. I'll need to investigate the changes to hedgehog's internals.
I'm working on this.
when designing hedgehog-classes, i realised that hedgehog would display source code from hedgehog-classes, since that is where the test actually exists - however, i didn't want to expose that to source to end users in error messages.
What I ended up doing was re-implementing a ton of hedgehog's pretty-printing internals, which was kind of painful.
I'm currently discussing with the hedgehog team what the best course of action is, since what I'm currently doing breaks hard, and often, especially because internals are not bound by PVP.
As an example, if i have the following:
newtype BadList a = BadList [a]
deriving (Eq,Show)
instance Foldable BadList where
foldMap f (BadList xs) = foldMap f xs
foldl' = foldl
hedgehog-classes will correctly identify that one's implementation of foldl'
is not strict. But, with just hedgehog's errors, one gets the following:
┏━━ src/Hedgehog/Classes/Foldable.hs ━━━
203 ┃ foldableFoldl' ::
204 ┃ ( Foldable f
205 ┃ , forall x. Eq x => Eq (f x), forall x. Show x => Show (f x)
206 ┃ ) => (forall x. Gen x -> Gen (f x)) -> Property
207 ┃ foldableFoldl' fgen = property $ do
208 ┃ xs <- forAll $ fgen (genBottom genSmallInteger)
┃ │ BadList [ undefined , 3 ]
209 ┃ let f :: Integer -> Bottom Integer -> Integer
210 ┃ f a b = case b of
211 ┃ BottomUndefined -> error "foldableFoldl': your foldl' is not strict!"
212 ┃ BottomValue v -> if even v then a else v
213 ┃ let z0 = 0
214 ┃ (rhs,ctx1) <- liftIO $ do
215 ┃ let f' x k z = k $! f z x
216 ┃ e <- try (evaluate (Foldable.foldr f' id xs z0))
217 ┃ case e of
218 ┃ Left (_ :: ErrorCall) -> pure (Nothing, ctxNotStrict "foldl'")
219 ┃ Right i -> pure (Just i, NoContext)
220 ┃ (lhs,ctx2) <- liftIO $ do
221 ┃ e <- try (evaluate (Foldable.foldl' f z0 xs))
222 ┃ case e of
223 ┃ Left (_ :: ErrorCall) -> pure (Nothing, ctxNotStrict "foldl'")
224 ┃ Right i -> pure (Just i, NoContext)
225 ┃ let ctx = case ctx1 of
226 ┃ NoContext -> case ctx2 of
227 ┃ NoContext -> contextualise $ LawContext
228 ┃ { lawContextLawName = "Foldl'"
229 ┃ , lawContextLawBody = "foldl' f z0 xs" `congruency` "foldr f' id xs z0, where f' x k z = k $! f z x"
230 ┃ , lawContextTcName = "Foldable"
231 ┃ , lawContextTcProp =
232 ┃ let showT = show xs
233 ┃ showF = "\\a b -> case a of\n BottomUndefined -> error \"foldableFoldr': not strict\"\n BottomValue v -> if even v then v else b"
234 ┃ showZ = show z0
235 ┃ in lawWhere
236 ┃ [ "foldl' f z0 xs" `congruency` "foldr f' id xs z0, where f' x k z = k $! f z x"
237 ┃ , "f = " ++ showF
238 ┃ , "z0 = " ++ showZ
239 ┃ , "t = " ++ showT
240 ┃ ]
241 ┃ , lawContextReduced = reduced lhs rhs
242 ┃ }
243 ┃ c2 -> c2
244 ┃ c1 -> c1
245 ┃ heqCtx lhs rhs ctx
━━━ Context ━━━
Your implementation of foldl' is not strict.
━━━━━━━━━━━━━━━
This failure can be reproduced by running:
> recheck (Size 15) (Seed 1777688920227310001 1361721854730653423) <property>
Foldable: foldl1 ✓ <interactive> passed 100 tests.
Foldable: foldr1 ✓ <interactive> passed 100 tests.
Foldable: toList ✓ <interactive> passed 100 tests.
Foldable: null ✓ <interactive> passed 100 tests.
Foldable: length ✓ <interactive> passed 100 tests.
Thank you! This is a wonderful library.
the hack i came up with involves using the silently
package and filtering out hedgehog's own output. hedgehog-classes-0.2 is now released.
also, thank you for your support of the package, and taking the time to open the issue. being reminded that there are users of my code really helps motivate me. so thanks.
Awesome, I will test this out in the next few days. Thank you!
Hi, any plans to support
hedgehog-1.0
? The current release (0.1.2) doesn't build with it: