@@ -21,10 +21,12 @@ import scalaz.std.option._
21
21
import scalaz .std .tuple ._
22
22
import scalaz .std .anyVal ._
23
23
24
+ import org .scalacheck ._
24
25
import org .specs2 .mutable ._
25
26
import org .typelevel .discipline .specs2 .mutable .Discipline
26
27
27
28
object MonadConversionSpecs extends Specification with Discipline {
29
+ import Arbitrary .arbitrary
28
30
29
31
" ifunctor" >> {
30
32
cats.functor.Invariant [Option ]
@@ -95,6 +97,71 @@ object MonadConversionSpecs extends Specification with Discipline {
95
97
checkAll(" Option" , TraverseTests [Option ].traverse[Int , Int , Int , Int , List , Option ])
96
98
}
97
99
100
+ " coflatmap" >> {
101
+ import scalaz .\&/
102
+
103
+ implicit def arbThese [A : Arbitrary , B : Arbitrary ]: Arbitrary [A \&/ B ] = {
104
+ val g = for {
105
+ a <- arbitrary[Option [A ]]
106
+
107
+ b <- if (a.isDefined)
108
+ arbitrary[Option [B ]]
109
+ else
110
+ arbitrary[B ].map(Some (_))
111
+
112
+ // we've defined things such that this is true, but keep the conditional anyway
113
+ if a.isDefined || b.isDefined
114
+ } yield {
115
+ (a, b) match {
116
+ case (Some (a), Some (b)) => \&/ .Both (a, b)
117
+ case (Some (a), None ) => \&/ .This (a)
118
+ case (None , Some (b)) => \&/ .That (b)
119
+ case _ => ???
120
+ }
121
+ }
122
+
123
+ Arbitrary (g)
124
+ }
125
+
126
+ implicit def cogenThese [A : Cogen , B : Cogen ]: Cogen [A \&/ B ] = Cogen { (s, t) =>
127
+ t match {
128
+ case \&/ .Both (a, b) => Cogen .perturb(Cogen .perturb(s, a), b)
129
+ case \&/ .This (a) => Cogen .perturb(s, a)
130
+ case \&/ .That (b) => Cogen .perturb(s, b)
131
+ }
132
+ }
133
+
134
+ cats.CoflatMap [Boolean \&/ ? ]
135
+ scalaz.Cobind [Boolean \&/ ? ]
136
+
137
+ " scalaz -> cats" >>
138
+ checkAll(" Boolean \\ &/ ?" , CoflatMapTests [Boolean \&/ ? ].coflatMap[Int , Int , Int ])
139
+ }
140
+
141
+ " comonad" >> {
142
+ import scalaz .{NonEmptyList => NEL }
143
+
144
+ implicit def arbNEL [A : Arbitrary ]: Arbitrary [NEL [A ]] = {
145
+ val g = for {
146
+ h <- arbitrary[A ]
147
+ t <- arbitrary[List [A ]]
148
+ } yield NEL (h, t : _* )
149
+
150
+ Arbitrary (g)
151
+ }
152
+
153
+ implicit def cogenNEL [A : Cogen ]: Cogen [NEL [A ]] = Cogen { (s, nel) =>
154
+ val s2 = Cogen .perturb(s, nel.head)
155
+ Cogen .perturb(s2, nel.tail.toList)
156
+ }
157
+
158
+ cats.Comonad [NEL ]
159
+ scalaz.Cobind [NEL ]
160
+
161
+ " scalaz -> cats" >>
162
+ checkAll(" NonEmptyList" , ComonadTests [NEL ].comonad[Int , Int , Int ])
163
+ }
164
+
98
165
" monad" >> {
99
166
" scalaz -> cats" >> {
100
167
" Option" >> {
0 commit comments