-
Notifications
You must be signed in to change notification settings - Fork 89
fix: Layer.using + add test for a failing case #1423
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
95dd0b6
a2e68ee
44f835f
bba926d
39be2cb
4e45d44
50e3f2c
0a1453c
dc4622b
2a543b7
6728db0
a3efcab
c07fef3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
ahoy-jon marked this conversation as resolved.
Show resolved
Hide resolved
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -47,12 +47,10 @@ abstract class Layer[+Out, -S] extends Serializable: | |
| * The output type of the composed layer | ||
| * @tparam S2 | ||
| * Additional effects of the composed layer | ||
| * @tparam In2 | ||
| * The input type required by the second layer | ||
| * @return | ||
| * A new layer representing the composition of both layers | ||
| */ | ||
| final infix def to[Out2, S2, In2](that: Layer[Out2, Env[In2] & S2]): Layer[Out2, S & S2] = To(self, that) | ||
| final infix def to[Out2, S2](that: Layer[Out2, Env[Out] & S2]): Layer[Out2, S & S2] = To(self, that) | ||
|
|
||
| /** Combines this layer with another independent layer. | ||
| * | ||
|
|
@@ -75,12 +73,12 @@ abstract class Layer[+Out, -S] extends Serializable: | |
| * The output type of the other layer | ||
| * @tparam S2 | ||
| * Additional effects of the other layer | ||
| * @tparam In2 | ||
| * The input type required by the second layer | ||
| * @return | ||
| * A new layer producing both outputs | ||
| */ | ||
| final infix def using[Out2, S2, In2](that: Layer[Out2, Env[In2] & S2]): Layer[Out & Out2, S & S2] = self and (self to that) | ||
| final infix def andTo[Out2, S2](that: Layer[Out2, Env[Out] & S2]): Layer[Out & Out2, S & S2] = self and (self to that) | ||
|
|
||
| final infix def using[Out2, S2](that: Layer[Out2, Env[Out] & S2]): Layer[Out & Out2, S & S2] = self andTo that | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
|
|
||
| end Layer | ||
|
|
||
|
|
@@ -93,7 +91,7 @@ object Layer: | |
| reduce(doRun(layer)) | ||
|
|
||
| /** An empty layer that produces no output. */ | ||
| val empty: Layer[Any, Any] = FromKyo { () => TypeMap.empty } | ||
| val empty: Layer[Any, Any] = FromKyo_0 { () => TypeMap.empty } | ||
|
|
||
| /** Creates a layer from a Kyo effect. | ||
| * | ||
|
|
@@ -107,7 +105,7 @@ object Layer: | |
| * A new layer wrapping the given effect | ||
| */ | ||
| def apply[A: Tag, S](kyo: => A < S)(using Frame): Layer[A, S] = | ||
| FromKyo { () => | ||
| FromKyo_0 { () => | ||
| kyo.map { result => TypeMap(result) } | ||
| } | ||
|
|
||
|
|
@@ -288,34 +286,31 @@ object Layer: | |
| kyo.internal.LayerMacros.make[Target](layers*) | ||
|
|
||
| private[kyo] object internal: | ||
| case class And[Out1, Out2, S1, S2](lhs: Layer[Out1, S1], rhs: Layer[Out2, S2]) extends Layer[Out1 & Out2, S1 & S2] | ||
| case class To[Out1, Out2, S1, S2](lhs: Layer[?, ?], rhs: Layer[?, ?]) extends Layer[Out1 & Out2, S1 & S2] | ||
| case class FromKyo[In, Out, S](kyo: () => TypeMap[Out] < (Env[In] & S))(using val tag: Tag[Out]) extends Layer[Out, S] | ||
|
|
||
| case class And[Out1, Out2, S1, S2](_1: Layer[Out1, S1], _2: Layer[Out2, S2]) extends Layer[Out1 & Out2, S1 & S2] | ||
| case class To[Out1, Out2, S1, S2](_1: Layer[Out1, S1], _2: Layer[Out2, S2 & Env[Out1]]) extends Layer[Out2, S1 & S2] | ||
| case class FromKyo_0[Out, S](kyo: () => TypeMap[Out] < S)(using val tag: Tag[Out]) extends Layer[Out, S] | ||
| case class FromKyo[In, Out, S](kyo: () => TypeMap[Out] < (Env[In] & S))(using val tag: Tag[Out]) extends Layer[Out, S & Env[In]] | ||
|
|
||
| class DoRun[Out, S] extends Serializable: | ||
| private given Frame = Frame.internal | ||
| private val memo = Memo[Layer[Out, S], TypeMap[Out], S & Memo] { self => | ||
| type Expected = TypeMap[Out] < (S & Memo) | ||
| self match | ||
| case And(lhs, rhs) => | ||
| { | ||
| for | ||
| leftResult <- doRun(lhs) | ||
| rightResult <- doRun(rhs) | ||
| yield leftResult.union(rightResult) | ||
| }.asInstanceOf[Expected] | ||
|
|
||
| case To(lhs, rhs) => | ||
| { | ||
| for | ||
| leftResult <- doRun(lhs) | ||
| rightResult <- Env.runAll(leftResult)(doRun(rhs)) | ||
| yield rightResult | ||
| }.asInstanceOf[Expected] | ||
| private type Expected = TypeMap[Out] < (S & Memo) | ||
| private val memo = Memo[Layer[Out, S], TypeMap[Out], S & Memo] { | ||
| case And(lhs, rhs) => | ||
| for | ||
| leftResult <- doRun(lhs) | ||
| rightResult <- doRun(rhs) | ||
| yield leftResult.union(rightResult) | ||
|
|
||
| case To(lhs, rhs) => | ||
| for | ||
| leftResult <- doRun(lhs) | ||
| rightResult <- Env.runAll(leftResult)(doRun(rhs)) | ||
| yield rightResult | ||
|
|
||
| case FromKyo(kyo) => | ||
| kyo().asInstanceOf[Expected] | ||
| end match | ||
| case FromKyo(kyo) => kyo() | ||
| case FromKyo_0(kyo) => kyo() | ||
|
Comment on lines
+312
to
+313
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since these will be materialized to the same expected type - I don't think we need a distinct variant. Can we keep it as just
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That would be nice, but
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we can just cast. There's no difference in the underlying representation due to type widening. |
||
| } | ||
| def apply(layer: Layer[Out, S]): TypeMap[Out] < (S & Memo) = memo(layer) | ||
| end DoRun | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.