Fwd: an idea for improving 'shrink'
Hi, since I got no response from the QuickCheck mail address, so I'm resending it here, if someone wants to comment on the idea. Best regards, Petr ---------- Forwarded message ---------- From: Petr Pudlák <petr.mvd@gmail.com> Date: 2014-07-06 20:13 GMT+02:00 Subject: an idea for improving 'shrink' To: QuickCheck developers <quickcheck@projects.haskell.org> Hi, I was learning about 'shrink' lately and I was trying to create some instances. It felt quite awkward until I realized that the operation for producing shrunk tuples is an applicative functor. I was playing with the idea for a while and I'm sending an experimental patch against QuickCheck master that shows the basics of the idea and how it can help constructing 'shrink' instances. If you feel that this is a good idea, let me know, I'll work on a full patch. Best regards, Petr
On Thu, Sep 4, 2014 at 1:06 PM, Petr Pudlák <petr.mvd@gmail.com> wrote:
since I got no response from the QuickCheck mail address, so I'm resending it here, if someone wants to comment on the idea.
I don't think it pays its way: it makes shrink a bit tidier, at the cost of breaking backwards compatibility in a widely used library.
2014-09-05 18:22 GMT+02:00 Bryan O’Sullivan <bos@serpentine.com>:
On Thu, Sep 4, 2014 at 1:06 PM, Petr Pudlák <petr.mvd@gmail.com> wrote:
since I got no response from the QuickCheck mail address, so I'm resending it here, if someone wants to comment on the idea.
I don't think it pays its way: it makes shrink a bit tidier, at the cost of breaking backwards compatibility in a widely used library.
That’s a problem. But I believe it the patch addresses it. QuickCheck always uses ‘shrink’, not ‘shrinkA’, and as the default implementation of ‘shrink’ is defined in terms of ‘shrinkA’, then it’s possible to define instances both using ‘shrink’ and using ‘shrinkA’. So both old code and new code that wants to take advantage of the Applicative interface work. I believe that in the long term this change would pay off: Compare the old code shrinkOne [] = [] shrinkOne (x:xs) = [ x':xs | x' <- shr x ] ++ [ x:xs' | xs' <- shrinkOne xs ] shrink (x, y) = [ (x', y) | x' <- shrink x ] ++ [ (x, y') | y' <- shrink y ] shrink (x, y, z) = [ (x', y', z') | (x', (y', z')) <- shrink (x, (y, z)) ] against the improved piece traverse shr xs -- replaces the whole shrinkOne shrinkA (x, y) = liftA2 (,) (shrinkA x) (shrinkA y) shrinkA (x, y, z) = liftA3 (,,) (shrinkA x) (shrinkA y) (shrinkA z)
On Sat, Sep 6, 2014 at 2:17 AM, Petr Pudlák <petr.mvd@gmail.com> wrote:
That’s a problem. But I believe it the patch addresses it. QuickCheck always uses ‘shrink’, not ‘shrinkA’, and as the default implementation of ‘shrink’ is defined in terms of ‘shrinkA’, then it’s possible to define instances both using ‘shrink’ and using ‘shrinkA’.
Ah, if you can retain backwards compatibility, then it becomes a lot more interesting...
participants (2)
-
Bryan O'Sullivan -
Petr Pudlák