@@ -155,6 +155,9 @@ object Hxl {
155155 ): Applicative [Hxl [F , * ]] = {
156156 implicit def self : Applicative [Hxl [F , * ]] = applicativeInstance[F , G ](fg, gf)
157157 type H [A ] = Hxl [F , A ]
158+ def suspend [A ](ha : => H [A ]): H [A ] = LiftF [F , A ](
159+ gf(Applicative [G ].unit.map(_ => ha))
160+ )
158161 new Applicative [H ] {
159162 def pure [A ](x : A ): H [A ] = Done (x)
160163 def ap [A , B ](ff : H [A => B ])(fa : H [A ]): H [B ] = {
@@ -164,21 +167,21 @@ object Hxl {
164167 case (h, LiftF (fa)) => LiftF (fa.map(h <*> _))
165168 case (at : AndThen [F , a1, A => B ], ab : AndThen [F , a2, A ]) =>
166169 AndThen [F , (a1, a2), B ](
167- self.tuple2(at.fa, ab.fa),
168- { case (a1, a2) => at.fb(a1).ap(ab.fb(a2)) }
170+ suspend( self.tuple2(at.fa, ab.fa) ),
171+ { case (a1, a2) => suspend( at.fb(a1).ap(ab.fb(a2) )) }
169172 )
170173
171174 // flatMap <*> batch -> move batch into left side of flatMap
172175 // to be optimistic. The choice is arbitrary.
173176 case (at : AndThen [F , a, A => B ], fb) =>
174177 AndThen [F , (a, A ), B ](
175- ( at.fa, fb).tupled,
176- { case (a, a2) => self.ap(at.fb(a))(Done (a2)) }
178+ suspend(( at.fa, fb).tupled) ,
179+ { case (a, a2) => suspend( self.ap(at.fb(a))(Done (a2) )) }
177180 )
178181 case (fa, ab : AndThen [F , a, A ]) =>
179182 AndThen [F , (A => B , a), B ](
180- ( fa, ab.fa).tupled,
181- { case (f, a2) => self.ap(Done (f))(ab.fb(a2)) }
183+ suspend(( fa, ab.fa).tupled) ,
184+ { case (f, a2) => suspend( self.ap(Done (f))(ab.fb(a2) )) }
182185 )
183186
184187 case (Done (f), Done (a)) => Done (f(a))
0 commit comments