Skip to content

Commit e10b2fa

Browse files
committed
fixes #1293, add zippable to combinators
1 parent ebbab1f commit e10b2fa

File tree

4 files changed

+64
-5
lines changed

4 files changed

+64
-5
lines changed

kyo-combinators/shared/src/main/scala/kyo/AsyncCombinators.scala

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package kyo
22

33
import kyo.debug.Debug
4+
import kyo.internal.Zippable
45
import kyo.kernel.ArrowEffect
56
import scala.annotation.tailrec
67
import scala.annotation.targetName
@@ -96,14 +97,15 @@ extension [A, E, Ctx](effect: A < (Abort[E] & Async & Ctx))
9697
using
9798
r: Reducible[Abort[E]],
9899
r1: Reducible[Abort[E1]],
99-
fr: Frame
100-
): (A, A1) < (r.SReduced & r1.SReduced & Async & Ctx & Ctx1) =
100+
fr: Frame,
101+
zippable: Zippable[A, A1]
102+
): zippable.Out < (r.SReduced & r1.SReduced & Async & Ctx & Ctx1) =
101103
for
102104
fiberA <- Fiber.run(using s)(effect)
103105
fiberA1 <- Fiber.run(using s2)(next)
104106
a <- fiberA.join
105107
a1 <- fiberA1.join
106-
yield (a, a1)
108+
yield zippable.zip(a, a1)
107109

108110
end extension
109111

kyo-combinators/shared/src/main/scala/kyo/KyoCombinators.scala

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package kyo
22

33
import kyo.Result.Error
44
import kyo.debug.Debug
5+
import kyo.internal.Zippable
56
import kyo.kernel.ArrowEffect
67
import scala.annotation.tailrec
78
import scala.annotation.targetName
@@ -42,8 +43,8 @@ extension [A, S](effect: A < S)
4243
* A computation that produces a tuple of both results
4344
*/
4445
@targetName("zip")
45-
def <*>[A1, S1](next: => A1 < S1)(using Frame): (A, A1) < (S & S1) =
46-
effect.map(e => next.map(n => (e, n)))
46+
def <*>[A1, S1](next: => A1 < S1)(using frame: Frame, zippable: Zippable[A, A1]): zippable.Out < (S & S1) =
47+
effect.map(e => next.map(n => zippable.zip(e, n)))
4748

4849
/** Performs this computation and prints its result to the console.
4950
*
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package kyo.internal
2+
3+
trait Zippable[-A, -B]:
4+
type Out
5+
def zip(left: A, right: B): Out
6+
7+
object Zippable extends ZippableLowPrio0:
8+
9+
given left[A]: (Zippable[A, Unit] { type Out = A }) = (left: A, _) => left
10+
given right[B]: (Zippable[Unit, B] { type Out = B }) = (_, right: B) => right
11+
12+
given concat[A <: Tuple, B <: Tuple]: (Zippable[A, B] { type Out = Tuple.Concat[A, B] }) = (left: A, right: B) => left ++ right
13+
14+
def apply[A, B](using z: Zippable[A, B]): Zippable[A, B] = z
15+
16+
def zip[A, B](a: A, b: B)(using z: Zippable[A, B]): z.Out = z.zip(a, b)
17+
end Zippable
18+
19+
trait ZippableLowPrio0 extends ZippableLowPrio1:
20+
given append[A <: Tuple, B]: (Zippable[A, B] { type Out = Tuple.Append[A, B] }) = (left: A, right: B) => left :* right
21+
22+
trait ZippableLowPrio1:
23+
given pair[A, B]: (Zippable[A, B] { type Out = (A, B) }) = (left: A, right: B) => (left, right)
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package kyo.internal
2+
3+
import kyo.*
4+
import org.scalatest.compatible.Assertion
5+
6+
class ZippableTest extends Test:
7+
"compile" - {
8+
def check[A, B](using zip: Zippable[A, B])[Expected](using (zip.Out =:= Expected)): Assertion = succeed
9+
10+
def on[A, B, C, D]: Assertion =
11+
check[(A, B), (C, D)][(A, B, C, D)]
12+
check[Unit, A][A]
13+
check[Unit, B][B]
14+
check[(A, B), Unit][(A, B)]
15+
check[(A, B), C][(A, B, C)]
16+
end on
17+
18+
}
19+
20+
"zip" in {
21+
assert(Zippable.zip(1, 2) == (1, 2))
22+
assert(Zippable.zip(1, ()) == 1)
23+
assert(Zippable.zip((), 2) == 2)
24+
assert(Zippable.zip((1, 2), 3) == (1, 2, 3))
25+
assert(Zippable.zip((1, 2), ()) == (1, 2))
26+
assert(Zippable.zip((), (3, 4)) == (3, 4))
27+
assert(Zippable.zip((1, 2), (3, 4)) == (1, 2, 3, 4))
28+
}
29+
30+
"prepend" in {
31+
assert(Zippable.zip(2, (3, 4)) == (2, (3, 4)))
32+
}
33+
end ZippableTest

0 commit comments

Comments
 (0)