-
-
Notifications
You must be signed in to change notification settings - Fork 205
Open
Description
A Scastie is provided here...
Scala 3.3.4,
SBT includes Monocle dependency of:
libraryDependencies ++= Seq(
"dev.optics" %% "monocle-core" % "3.3.0",
"dev.optics" %% "monocle-macro" % "3.3.0"
)import monocle.syntax.all.*
trait Algebra[Result[_], Element]:
def empty: Result[Element]
def addSomething(
partialResult: Result[Element],
newData: String
): Result[Element]
end Algebra
def weeklyGrind[Result[_], Element](
algebra: Algebra[Result, Element]
): Result[Element] =
val monday = algebra.empty
val tuesday = algebra.addSomething(monday, "A hard working day.")
// Long weekend follows...
tuesday
end weeklyGrind
type Steps[Element] =
Vector[[Result[Element]] => Algebra[Result, Element] => Result[
Element
] => Result[Element]]
// Polymorphic because we don't know what kind of result
// the downstream algebra will work with.
case class Recording[Element](steps: Vector[[Result[Element]] => Algebra[Result, Element] => Result[
Element
] => Result[Element]]):
// Changing to the commented out definition fixes the Monocle error...
/*case class Recording[Element](steps: Steps[Element]):*/
def playback[Result[Element]](
algebra: Algebra[Result, Element]
): Result[Element] =
steps.foldLeft(algebra.empty)((partialResult, step) =>
step(algebra)(partialResult)
)
class RecordingAlgebra[Element] extends Algebra[Recording, Element]:
def empty: Recording[Element] =
Recording(steps = Vector.empty)
def addSomething(
partialResult: Recording[Element],
newData: String
): Recording[Element] =
partialResult
.focus(_.steps)
.modify(
_.appended(
[Result[_]] =>
(downstreamAlgebra: Algebra[Result, Element]) =>
downstreamAlgebra.addSomething(_, newData)
)
)
end RecordingAlgebra
val onTheRecord = weeklyGrind(new RecordingAlgebra)Note the alternative definition of Recording:
case class Recording[Element](steps: Vector[[Result[Element]] => Algebra[Result, Element] => Result[
Element
] => Result[Element]]):
// Changing to the commented out definition fixes the Monocle error...
/*case class Recording[Element](steps: Steps[Element]):*/In the uncommented form, the macro expansion of the .focus(_.steps).modify(...) call in RecordingAlgebra fails with:
Exception occurred while executing macro expansion.
scala.quoted.runtime.impl.ExprCastException:
Expected type:
scala.collection.immutable.Vector[scala.PolyFunction {
val apply: [Result _ >: scala.Nothing <: [Element >: scala.Nothing <: scala.Any] => scala.Any](x$1: Playground.Algebra[Result, Recording.this.Element])scala.Function1[Result[Recording.this.Element], Result[Recording.this.Element]]
}]
Actual type: from.steps
Expression: from.steps
at scala.quoted.runtime.impl.ExprCastException$.apply(ExprCastException.scala:15)
at scala.quoted.runtime.impl.QuotesImpl.asExprOf(QuotesImpl.scala:75)
at scala.quoted.runtime.impl.QuotesImpl$reflect$TreeMethods$.asExprOf(QuotesImpl.scala:123)
at scala.quoted.runtime.impl.QuotesImpl$reflect$TreeMethods$.asExprOf(QuotesImpl.scala:122)
at monocle.internal.focus.features.selectonlyfield.SelectOnlyFieldGenerator.generateSelectOnlyField$$anonfun$1$$anonfun$1(SelectOnlyFieldGenerator.scala:24)
at monocle.internal.focus.features.selectonlyfield.SelectOnlyFieldGenerator.generateSelectOnlyField$$anonfun$1(SelectOnlyFieldGenerator.scala:24)
at monocle.internal.focus.features.selectonlyfield.SelectOnlyFieldGenerator.generateSelectOnlyField$$anonfun$adapted$1(SelectOnlyFieldGenerator.scala:25)
at dotty.tools.dotc.quoted.PickledQuotes$$anon$1.transform(PickledQuotes.scala:110)
Using the commented form uses an equivalent type alias, and compiles correctly.
I'm not sure if this is down to Monocle, or is an issue with the Scala compiler itself.
The workaround is available (and looks better anyway), but I've raised this in case there is a deeper issue - but it's not urgent for me.
Metadata
Metadata
Assignees
Labels
No labels