haskell-hedgehog icon indicating copy to clipboard operation
haskell-hedgehog copied to clipboard

Automatically generating random values based on types?

Open saurabhnanda opened this issue 7 years ago • 7 comments
trafficstars

(newbie alert)

Was looking around in https://hackage.haskell.org/package/hedgehog-0.5/docs/Hedgehog-Gen.html and it wasn't obvious to me how to generate random data based on the type of the value. To draw a parallel, I have used the following technique with QC:

instance Arbitrary TxnSource where
  arbitrary = genericArbitrary uniform

instance Arbitrary Nouns where
  arbitrary = genericArbitrary uniform

instance Arbitrary BookingId where
  arbitrary = genericArbitrary uniform

instance Arbitrary TLSOption where
  arbitrary = arbitraryBoundedEnum

saurabhnanda avatar Dec 05 '17 10:12 saurabhnanda

Hey Saurabh,

Hedgehog has no equivalent to the Arbitrary typeclass. This is intentional. Arbitrary is a lawless typeclass that inevitably leads to either orphan instances or a viral QuickCheck dependency in your production libraries. The corresponding idiom is merely to give your generators names and call them by those names.

If you really want typeclass-based overloading, you could:

  • Write your own typeclass
  • Interoperate with QuickCheck's Arbitrary class using hedgehog-quickcheck

Closing for now, can reopen if you have further questions or if you feel this was not adequately addressed.

thumphries avatar Dec 05 '17 18:12 thumphries

I understand that hedgehog has no equivalent of the Arbitrary typeclass, but the question was more about hedgehog's equivalent of the genericArbitrary function. It "inspects" the type of the required value and automatically generates random data in that shape. Any generics or TH equivalent to do that in hedgehog?

saurabhnanda avatar Dec 06 '17 01:12 saurabhnanda

There's nothing like that right now - that might be a good addition or standalone library though! Sometimes you really do want totally unconstrained derived generators / fuzzers.

On Dec 5, 2017, at 5:46 PM, Saurabh Nanda [email protected] wrote:

I understand that hedgehog has no equivalent of the Arbitrary typeclass, but the question was more about hedgehog's equivalent of the genericArbitrary function. It "inspects" the type of the required value and automatically generates random data in that shape. Any generics or TH equivalent to do that in hedgehog?

— You are receiving this because you modified the open/close state. Reply to this email directly, view it on GitHub, or mute the thread.

thumphries avatar Dec 06 '17 01:12 thumphries

Things like this are also possible.

dalaing avatar Dec 06 '17 02:12 dalaing

@saurabhnanda sorry for misreading your original question - I was blinded by instance Arbitrary. Reopening as a feature request / suggestion

Unsure if this is better off as a Hedgehog feature, a library built on top of Hedgehog, or an entirely separate thing like Yorgey's blog post.

thumphries avatar Dec 06 '17 03:12 thumphries

@thumphries, @dalaing, we had a similar discussion around this with @jystic in https://github.com/hedgehogqa/fsharp-hedgehog/issues/139#issuecomment-338966392 for fsharp-hedgehog.

There, we ended up doing it in a separate library that we called fsharp-hedgehog-experimental. Perhaps we want to do something similar also here(?)

We used an approach similar to this one, but in F#, and we ended up with a generator called auto that (in F#) takes anof a and that returns a Gen a.

moodmosaic avatar Dec 06 '17 03:12 moodmosaic

Hi, I've just uploaded the package hedgehog-generic (docs yet to build, because I've just uploaded a few minutes ago): http://hackage.haskell.org/package/hedgehog-generic

Perhaps this may be useful to you, @saurabhnanda? It allows you to do something like

import Hedgehog
import Hedgehog.Generic

data Foo = Foo
  { _fooX :: X
  , _fooY :: Y
  } deriving (Generic)

-- equivalent to `genFoo = Foo <$> hgen <*> hgen`
genFoo :: Gen Foo
genFoo = hgen

There is one small semantic difference in that we require a Generic instance on all fields of a type, rather than an Arbitrary instance, because of course we do not have one.

chessai avatar Apr 17 '19 15:04 chessai