
Dear café, I want to implement a roundtrip test for a parser/prettyprinter combination. Let me try to explain what I am struggling with. I start with some type definitions of functions I have *data Guarded a =* * Errors (NE.NonEmpty CtxError) | Checked a [Warning]* *parseFoo :: Text -> Guarded Foo* *prettyFoo :: Foo -> Text* The idea is that for all foo :: Foo, the following holds: *parseFoo . prettyFoo $ foo* should be equal to *Checked foo []* Now, if there is a counterexample, I would like to see prettyFoo foo as output, folowed by the show of the Errors part. I have been struggling to get this working, but without luck so far. I am not very familiar with Quickcheck, so that could be the problem too. Any help would be appreciated! Thanks Han

Hello Han On 11-06-21 17:16, Han Joosten wrote:
[..] *parseFoo :: Text -> Guarded Foo* *prettyFoo :: Foo -> Text*
The idea is that for all foo :: Foo, the following holds: *parseFoo . prettyFoo $ foo* should be equal to *Checked foo []*
Now, if there is a counterexample, I would like to see prettyFoo foo as output, folowed by the show of the Errors part.
It seems you know what property should hold for `parseFoo` and `prettyFoo`. Per the QuickCheck manual [1] this could be written as import Test.QuickCheck propOnAllFooText :: Property propOnAllFooText = forAll (arbitrary :: Gen Foo) $ \exFoo -> parseFoo (prettyFoo exFoo) == Checked exFoo [] What you are missing is a way to generate the test cases (the `arbitrary' generator above). You need a way to declare this instance instance Arbitrary Foo where -- arbitrary :: Gen Foo arbitrary = <something> You can see example on how to define it on the manual [1]. Good luck. [1]: http://www.cse.chalmers.se/~rjmh/QuickCheck/manual.html -- -- Rubén -- pgp: 4EE9 28F7 932E F4AD

Thanks for this respons, Rubén. I might not have explained what I am
looking for very well.
I already have
instance Arbitrary Foo
That is not the problem. The problem is, that when a counterexample is
found, it is dumped to the output with the `show` function. I would like to
be able to use another function for that, say show'. In order to do so, I
need to obtain the counterexample itself in some way, so I can use it to
generate a useful message after the tests are done.
Op vr 11 jun. 2021 om 23:31 schreef Ruben Astudillo
Hello Han
On 11-06-21 17:16, Han Joosten wrote:
[..] *parseFoo :: Text -> Guarded Foo* *prettyFoo :: Foo -> Text*
The idea is that for all foo :: Foo, the following holds: *parseFoo . prettyFoo $ foo* should be equal to *Checked foo []*
Now, if there is a counterexample, I would like to see prettyFoo foo as output, folowed by the show of the Errors part.
It seems you know what property should hold for `parseFoo` and `prettyFoo`. Per the QuickCheck manual [1] this could be written as
import Test.QuickCheck
propOnAllFooText :: Property propOnAllFooText = forAll (arbitrary :: Gen Foo) $ \exFoo -> parseFoo (prettyFoo exFoo) == Checked exFoo []
What you are missing is a way to generate the test cases (the `arbitrary' generator above). You need a way to declare this instance
instance Arbitrary Foo where -- arbitrary :: Gen Foo arbitrary = <something>
You can see example on how to define it on the manual [1]. Good luck.
[1]: http://www.cse.chalmers.se/~rjmh/QuickCheck/manual.html
-- -- Rubén -- pgp: 4EE9 28F7 932E F4AD

You say you have another function show' :: Foo -> String. Then how about defining newtype AnotherFoo = AnotherFoo Foo instance Show AnotherFoo where show (AnotherFoo foo) = show' food instance Arbitrary AnotherFoo where arbitrary = AnotherFoo <$> arbitrary etc.? On Sat, Jun 12, 2021 at 12:49:47PM +0200, Han Joosten wrote:
Thanks for this respons, Rubén. I might not have explained what I am looking for very well. I already have instance Arbitrary Foo That is not the problem. The problem is, that when a counterexample is found, it is dumped to the output with the `show` function. I would like to be able to use another function for that, say show'. In order to do so, I need to obtain the counterexample itself in some way, so I can use it to generate a useful message after the tests are done.
Op vr 11 jun. 2021 om 23:31 schreef Ruben Astudillo
: Hello Han
On 11-06-21 17:16, Han Joosten wrote:
[..] *parseFoo :: Text -> Guarded Foo* *prettyFoo :: Foo -> Text*
The idea is that for all foo :: Foo, the following holds: *parseFoo . prettyFoo $ foo* should be equal to *Checked foo []*
Now, if there is a counterexample, I would like to see prettyFoo foo as output, folowed by the show of the Errors part.
It seems you know what property should hold for `parseFoo` and `prettyFoo`. Per the QuickCheck manual [1] this could be written as
import Test.QuickCheck
propOnAllFooText :: Property propOnAllFooText = forAll (arbitrary :: Gen Foo) $ \exFoo -> parseFoo (prettyFoo exFoo) == Checked exFoo []
What you are missing is a way to generate the test cases (the `arbitrary' generator above). You need a way to declare this instance
instance Arbitrary Foo where -- arbitrary :: Gen Foo arbitrary = <something>
You can see example on how to define it on the manual [1]. Good luck.
[1]: http://www.cse.chalmers.se/~rjmh/QuickCheck/manual.html
-- -- Rubén -- pgp: 4EE9 28F7 932E F4AD

I think you're looking for something like this:
```
prop_parser :: Foo -> Property
prop_parser foo =
case parserFoo pretty of
Checked foo' [] | foo == foo' -> property True
a -> counterexample (show a ++ "\n" ++ show pretty) False
where
pretty = prettyFoo foo
```
Sent with ProtonMail Secure Email.
‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐
On Saturday, June 12th, 2021 at 12:49, Han Joosten
Thanks for this respons, Rubén. I might not have explained what I am looking for very well. I already have instance Arbitrary Foo That is not the problem. The problem is, that when a counterexample is found, it is dumped to the output with the `show` function. I would like to be able to use another function for that, say show'. In order to do so, I need to obtain the counterexample itself in some way, so I can use it to generate a useful message after the tests are done.
Op vr 11 jun. 2021 om 23:31 schreef Ruben Astudillo
:
Hello Han
On 11-06-21 17:16, Han Joosten wrote:
[..]
*parseFoo :: Text -> Guarded Foo*
*prettyFoo :: Foo -> Text*
The idea is that for all foo :: Foo, the following holds:
*parseFoo . prettyFoo $ foo* should be equal to *Checked foo []*
Now, if there is a counterexample, I would like to see prettyFoo foo as
output, folowed by the show of the Errors part.
It seems you know what property should hold for `parseFoo` and `prettyFoo`.
Per the QuickCheck manual [1] this could be written as
import Test.QuickCheck
propOnAllFooText :: Property
propOnAllFooText = forAll (arbitrary :: Gen Foo) $ \exFoo ->
parseFoo (prettyFoo exFoo) == Checked exFoo []
What you are missing is a way to generate the test cases (the `arbitrary'
generator above). You need a way to declare this instance
instance Arbitrary Foo where
-- arbitrary :: Gen Foo
arbitrary = <something>
You can see example on how to define it on the manual [1]. Good luck.
[1]: http://www.cse.chalmers.se/~rjmh/QuickCheck/manual.html
--
-- Rubén
-- pgp: 4EE9 28F7 932E F4AD

On Sat, 12 Jun 2021, Han Joosten wrote:
Thanks for this respons, Rubén. I might not have explained what I am looking for very well. I already have instance Arbitrary Foo That is not the problem. The problem is, that when a counterexample is found, it is dumped to the output with the `show` function. I would like to be able to use another function for that, say show'. In order to do so, I need to obtain the counterexample itself in some way, so I can use it to generate a useful message after the tests are done.
https://hackage.haskell.org/package/QuickCheck-2.14.2/docs/Test-QuickCheck.h...

Thanks all for the responses. I managed to put them all together and I [got it all to work]( https://github.com/AmpersandTarski/Ampersand/blob/cefbc08ad8fb3152ce1a55dce5... ). Cheers, Han. Op za 12 jun. 2021 om 13:28 schreef Henning Thielemann < lemming@henning-thielemann.de>:
On Sat, 12 Jun 2021, Han Joosten wrote:
Thanks for this respons, Rubén. I might not have explained what I am looking for very well. I already have instance Arbitrary Foo That is not the problem. The problem is, that when a counterexample is found, it is dumped to the output with the `show` function. I would like to be able to use another function for that, say show'. In order to do so, I need to obtain the counterexample itself in some way, so I can use it to generate a useful message after the tests are done.
https://hackage.haskell.org/package/QuickCheck-2.14.2/docs/Test-QuickCheck.h...
participants (5)
-
coot@coot.me
-
Han Joosten
-
Henning Thielemann
-
Ruben Astudillo
-
Tom Ellis