-
Notifications
You must be signed in to change notification settings - Fork 243
/
ArbitrarySupport.scala
144 lines (119 loc) · 4.36 KB
/
ArbitrarySupport.scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
package spire.math
import spire.algebra._
import org.scalatest.Matchers
import org.scalacheck.Arbitrary._
import org.scalatest._
import prop._
import org.scalacheck._
import Gen._
import Arbitrary.arbitrary
object ArbitrarySupport {
object Ordinal {
trait _0
trait _1
trait _2
trait _3
trait _4
trait _5
trait _6
trait _7
trait _8
trait _9
trait _10
trait _20
trait _50
trait _100
}
abstract class Size[A](val value: Int)
object Size {
import Ordinal._
implicit object Size0 extends Size[_0](0)
implicit object Size1 extends Size[_1](1)
implicit object Size2 extends Size[_2](2)
implicit object Size3 extends Size[_3](3)
implicit object Size4 extends Size[_4](4)
implicit object Size5 extends Size[_5](5)
implicit object Size6 extends Size[_6](6)
implicit object Size7 extends Size[_3](7)
implicit object Size8 extends Size[_3](8)
implicit object Size9 extends Size[_3](9)
implicit object Size10 extends Size[_10](10)
implicit object Size20 extends Size[_20](20)
implicit object Size50 extends Size[_50](50)
implicit object Size100 extends Size[_100](100)
def apply[A](implicit sz: Size[A]): Int = sz.value
}
case class Sized[A, L, U](num: A)
case class Positive[A](num: A)
case class Negative[A](num: A)
case class NonZero[A](num: A)
case class NonPositive[A](num: A)
case class NonNegative[A](num: A)
import spire.syntax.all._
implicit def sized[A: EuclideanRing: Signed: Arbitrary, L: Size, U: Size]: Arbitrary[Sized[A, L, U]] =
Arbitrary(arbitrary[A].map(a => Sized((a % (Size[U] - Size[L])).abs + Size[L])))
implicit def positive[A: Signed: Arbitrary]: Arbitrary[Positive[A]] =
Arbitrary(arbitrary[A].map(_.abs).filter(_.signum > 0).map(Positive(_)))
implicit def negative[A: Signed: AdditiveGroup: Arbitrary]: Arbitrary[Negative[A]] =
Arbitrary(arbitrary[A].map(-_.abs).filter(_.signum < 0).map(Negative(_)))
implicit def nonZero[A: Signed: AdditiveGroup: Arbitrary]: Arbitrary[NonZero[A]] =
Arbitrary(arbitrary[A].filter(_.signum != 0).map(NonZero(_)))
implicit def nonPositive[A: Signed: AdditiveGroup: Arbitrary]: Arbitrary[NonPositive[A]] =
Arbitrary(arbitrary[A].map(-_.abs).filter(_.signum < 1).map(NonPositive(_)))
implicit def nonNegative[A: Signed: AdditiveGroup: Arbitrary]: Arbitrary[NonNegative[A]] =
Arbitrary(arbitrary[A].map(_.abs).filter(_.signum > -1).map(NonNegative(_)))
implicit val ubyte: Arbitrary[UByte] =
Arbitrary(arbitrary[Byte].map(n => UByte(n)))
implicit val ushort: Arbitrary[UShort] =
Arbitrary(arbitrary[Short].map(n => UShort(n)))
implicit val uint: Arbitrary[UInt] =
Arbitrary(arbitrary[Int].map(n => UInt(n)))
implicit val ulong: Arbitrary[ULong] =
Arbitrary(arbitrary[Long].map(n => ULong(n)))
implicit val natural: Arbitrary[Natural] =
Arbitrary(arbitrary[BigInt].map(n => Natural(n.abs)))
implicit val safeLong: Arbitrary[SafeLong] =
Arbitrary(arbitrary[BigInt].map(n => SafeLong(n)))
implicit val rational: Arbitrary[Rational] =
Arbitrary(for {
n <- arbitrary[Long]
d <- arbitrary[Long].filter(_ != 0)
} yield {
Rational(n, d)
})
implicit val real: Arbitrary[Real] =
Arbitrary(arbitrary[Rational].map(n => Real(n)))
implicit def complex[A: Arbitrary: Fractional: Signed: Trig]: Arbitrary[Complex[A]] =
Arbitrary(for {
re <- arbitrary[A]
im <- arbitrary[A]
} yield {
Complex(re, im)
})
implicit def quaternion[A: Arbitrary: Fractional: Signed: Trig]: Arbitrary[Quaternion[A]] =
Arbitrary(for {
r <- arbitrary[A]
i <- arbitrary[A]
j <- arbitrary[A]
k <- arbitrary[A]
} yield {
Quaternion(r, i, j, k)
})
implicit def interval[A: Arbitrary: Order: AdditiveMonoid]: Arbitrary[Interval[A]] = {
Arbitrary(for {
n <- arbitrary[Double]
lower <- arbitrary[A]
upper <- arbitrary[A]
} yield {
if (n < 0.05) Interval.all[A]
else if (n < 0.10) Interval.above(lower)
else if (n < 0.15) Interval.atOrAbove(lower)
else if (n < 0.20) Interval.below(upper)
else if (n < 0.25) Interval.atOrBelow(upper)
else if (n < 0.50) Interval.open(lower, upper)
else if (n < 0.60) Interval.openBelow(lower, upper)
else if (n < 0.70) Interval.openAbove(lower, upper)
else Interval.closed(lower, upper)
})
}
}