4

I have a type Foo with a constructor that takes an Int. How do I define an implicit Arbitrary for Foo to be used with scalacheck?

implicit def arbFoo: Arbitrary[Foo] = ???

I came up with the following solution, but it's a bit too "manual" and low-level for my taste:

val fooGen = for (i <- Gen.choose(Int.MinValue, Int.MaxValue)) yield new Foo(i)

implicit def arbFoo: Arbitrary[Foo] = Arbitrary(fooGen)

Ideally, I would want a higher-order function where I just have to plug in an Int => Foo function.


I managed to cut it down to:

implicit def arbFoo = Arbitrary(Gen.resultOf((i: Int) => new Foo(i)))

But I still feel like there has got to be a slightly simpler way.

fredoverflow
  • 256,549
  • 94
  • 388
  • 662

1 Answers1

2

Well, you can use the underscore notation instead of defining the whole Foo-creating function as (i: Int) => new Foo(i)):

class Foo(i: Int)

(1 to 3).map(new Foo(_))

This works because Scala knows that Foo takes an Int, and that map is mapping over Ints, so there's no need to spell it all out explicitly.

So this is a bit shorter:

implicit def arbFoo = Arbitrary(Gen.resultOf(new Foo(_)))
dhg
  • 52,383
  • 8
  • 123
  • 144
  • 1
    Actually, case classes are handled as functions in Scala, so you can write it even simpler: `implicit def arbFoo = Arbitrary(Gen.resultOf(Foo))`. – Rickard Nilsson May 30 '12 at 22:37