MatchError using `as` inside Focus
kenbot opened this issue · comments
Ken Scambler commented
Playing with this codebase: https://github.com/bblfish/lens-play/blob/master/src/main/scala/server/Server.scala
sbt> console
scala> import monocle.syntax.all._; import server._; import Server._
scala> val container = Container(Map("foo" -> Container(Map("bar" -> TextResource("banana")))))
val container: server.Server.Container = Container(Map(foo -> Container(Map(bar -> TextResource(banana,2021-09-01T13:29:42.917567400Z)),2021-09-01T13:29:42.917567400Z)),2021-09-01T13:29:42.917567400Z)
// External as works:
scala> container.focus(_.index(List("foo", "bar"))).as[TextResource].getOption
val res2: Option[server.Server.TextResource] = Some(TextResource(banana,2021-09-01T13:29:42.917567400Z))
// Internal as fails:
scala> container.focus(_.index(List("foo", "bar")).as[TextResource]).getOption
1 |container.focus(_.index(List("foo", "bar")).as[TextResource]).getOption
|^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|Exception occurred while executing macro expansion.
|scala.MatchError: Skolem(1798376932) (of class dotty.tools.dotc.core.Types$SkolemType)
| at scala.quoted.runtime.impl.printers.Extractors$ExtractorsPrinter.visitType(Extractors.scala:233)
| at scala.quoted.runtime.impl.printers.Extractors$.showType(Extractors.scala:12)
| at scala.quoted.runtime.impl.QuotesImpl$$anon$17.show(QuotesImpl.scala:2898)
| at scala.quoted.runtime.impl.QuotesImpl$$anon$17.show(QuotesImpl.scala:2897)
| at scala.quoted.runtime.impl.QuotesImpl$reflect$TypeReprMethods$.show(QuotesImpl.scala:1660)
| at scala.quoted.runtime.impl.QuotesImpl$reflect$TypeReprMethods$.show(QuotesImpl.scala:1660)
| at scala.quoted.runtime.impl.printers.SourceCode$SourceCodePrinter.printType(SourceCode.scala:1228)
| at scala.quoted.runtime.impl.printers.SourceCode$SourceCodePrinter.printType(SourceCode.scala:1102)
| at scala.quoted.runtime.impl.printers.SourceCode$SourceCodePrinter.printSeparated$9(SourceCode.scala:730)
| at scala.quoted.runtime.impl.printers.SourceCode$SourceCodePrinter.printTypesOrBounds(SourceCode.scala:736)
| at scala.quoted.runtime.impl.printers.SourceCode$SourceCodePrinter.printType$$anonfun$2(SourceCode.scala:1137)
| at scala.quoted.runtime.impl.printers.SourceCode$SourceCodePrinter.inSquare(SourceCode.scala:88)
| at scala.quoted.runtime.impl.printers.SourceCode$SourceCodePrinter.printType(SourceCode.scala:1137)
| at scala.quoted.runtime.impl.printers.SourceCode$.showType(SourceCode.scala:13)
| at scala.quoted.runtime.impl.QuotesImpl$$anon$14.show(QuotesImpl.scala:2886)
| at scala.quoted.runtime.impl.QuotesImpl$$anon$14.show(QuotesImpl.scala:2885)
| at scala.quoted.runtime.impl.QuotesImpl$reflect$TypeReprMethods$.show(QuotesImpl.scala:1660)
| at scala.quoted.runtime.impl.QuotesImpl$reflect$TypeReprMethods$.show(QuotesImpl.scala:1660)
| at monocle.internal.focus.features.as.AsParser$KeywordAs$.unapply(AsParser.scala:17)
| at monocle.internal.focus.features.ParserLoop.loop$1(ParserLoop.scala:50)
| at monocle.internal.focus.features.ParserLoop.parseFocusActions(ParserLoop.scala:64)
| at monocle.internal.focus.features.ParserLoop.parseFocusActions$(ParserLoop.scala:27)
| at monocle.internal.focus.FocusImpl.parseFocusActions(FocusImpl.scala:7)
| at monocle.internal.focus.FocusImpl.$anonfun$1(FocusImpl.scala:20)
| at scala.util.Either.flatMap(Either.scala:352)
| at monocle.internal.focus.FocusImpl.run(FocusImpl.scala:22)
| at monocle.internal.focus.FocusImpl$.apply(FocusImpl.scala:33)
| at monocle.internal.focus.AppliedFocusImpl$.apply(AppliedFocusImpl.scala:13)
|
| This location contains code that was inlined from rs$line$10:1
Ken Scambler commented
Here's another one, this time from an index
call:
val i = summon[Index[Resource[?], List[String], Resource[?]]]
server.focus(_.index(path)(using i))
Exception occurred while executing macro expansion.
scala.MatchError: Skolem(165252930) (of class dotty.tools.dotc.core.Types$SkolemType)
at scala.quoted.runtime.impl.printers.Extractors$ExtractorsPrinter.visitType(Extractors.scala:233)
at scala.quoted.runtime.impl.printers.Extractors$.showType(Extractors.scala:12)
at scala.quoted.runtime.impl.QuotesImpl$$anon$17.show(QuotesImpl.scala:2898)
at scala.quoted.runtime.impl.QuotesImpl$$anon$17.show(QuotesImpl.scala:2897)
at scala.quoted.runtime.impl.QuotesImpl$reflect$TypeReprMethods$.show(QuotesImpl.scala:1660)
at scala.quoted.runtime.impl.QuotesImpl$reflect$TypeReprMethods$.show(QuotesImpl.scala:1660)
at scala.quoted.runtime.impl.printers.SourceCode$SourceCodePrinter.printType(SourceCode.scala:1228)
at scala.quoted.runtime.impl.printers.SourceCode$SourceCodePrinter.printType(SourceCode.scala:1102)
at scala.quoted.runtime.impl.printers.SourceCode$SourceCodePrinter.printSeparated$9(SourceCode.scala:730)
at scala.quoted.runtime.impl.printers.SourceCode$SourceCodePrinter.printTypesOrBounds(SourceCode.scala:736)
at scala.quoted.runtime.impl.printers.SourceCode$SourceCodePrinter.printType$$anonfun$2(SourceCode.scala:1137)
at scala.quoted.runtime.impl.printers.SourceCode$SourceCodePrinter.inSquare(SourceCode.scala:88)
at scala.quoted.runtime.impl.printers.SourceCode$SourceCodePrinter.printType(SourceCode.scala:1137)
at scala.quoted.runtime.impl.printers.SourceCode$SourceCodePrinter.printSeparated$9(SourceCode.scala:732)
at scala.quoted.runtime.impl.printers.SourceCode$SourceCodePrinter.printTypesOrBounds(SourceCode.scala:736)
at scala.quoted.runtime.impl.printers.SourceCode$SourceCodePrinter.printType$$anonfun$2(SourceCode.scala:1137)
at scala.quoted.runtime.impl.printers.SourceCode$SourceCodePrinter.inSquare(SourceCode.scala:88)
at scala.quoted.runtime.impl.printers.SourceCode$SourceCodePrinter.printType(SourceCode.scala:1137)
at scala.quoted.runtime.impl.printers.SourceCode$.showType(SourceCode.scala:13)
at scala.quoted.runtime.impl.QuotesImpl$$anon$14.show(QuotesImpl.scala:2886)
at scala.quoted.runtime.impl.QuotesImpl$$anon$14.show(QuotesImpl.scala:2885)
at scala.quoted.runtime.impl.QuotesImpl.asExprOf(QuotesImpl.scala:71)
at scala.quoted.runtime.impl.QuotesImpl$reflect$TreeMethods$.asExprOf(QuotesImpl.scala:113)
at scala.quoted.runtime.impl.QuotesImpl$reflect$TreeMethods$.asExprOf(QuotesImpl.scala:112)
at monocle.internal.focus.features.index.IndexGenerator.generateIndex$$anonfun$4(IndexGenerator.scala:15)
at monocle.internal.focus.features.index.IndexGenerator.generateIndex$$anonfun$adapted$2(IndexGenerator.scala:15)
at dotty.tools.dotc.quoted.PickledQuotes$$anon$1.transform(PickledQuotes.scala:82)
at dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1367)
at dotty.tools.dotc.quoted.PickledQuotes$$anon$1.transform(PickledQuotes.scala:107)
at dotty.tools.dotc.quoted.PickledQuotes$$anon$1.transform(PickledQuotes.scala:97)
at dotty.tools.dotc.ast.Trees$Instance$TreeMap.transform(Trees.scala:1333)
at dotty.tools.dotc.quoted.PickledQuotes$$anon$1.transform(PickledQuotes.scala:107)
at dotty.tools.dotc.quoted.PickledQuotes$.spliceTerms(PickledQuotes.scala:122)
at dotty.tools.dotc.quoted.PickledQuotes$.unpickleTerm(PickledQuotes.scala:61)
at scala.quoted.runtime.impl.QuotesImpl.unpickleExpr(QuotesImpl.scala:2913)
at monocle.internal.focus.features.index.IndexGenerator.generateIndex(IndexGenerator.scala:15)
at monocle.internal.focus.features.index.IndexGenerator.generateIndex$(IndexGenerator.scala:6)
at monocle.internal.focus.FocusImpl.generateIndex(FocusImpl.scala:7)
at monocle.internal.focus.features.GeneratorLoop.generateActionCode(GeneratorLoop.scala:48)
at monocle.internal.focus.features.GeneratorLoop.generateCode$$anonfun$2$$anonfun$1(GeneratorLoop.scala:36)
at scala.util.Either.flatMap(Either.scala:352)
at monocle.internal.focus.features.GeneratorLoop.generateCode$$anonfun$1(GeneratorLoop.scala:36)
at scala.collection.LinearSeqOps.foldLeft(LinearSeq.scala:169)
at scala.collection.LinearSeqOps.foldLeft$(LinearSeq.scala:165)
at scala.collection.immutable.List.foldLeft(List.scala:79)
at monocle.internal.focus.features.GeneratorLoop.generateCode(GeneratorLoop.scala:36)
at monocle.internal.focus.features.GeneratorLoop.generateCode$(GeneratorLoop.scala:27)
at monocle.internal.focus.FocusImpl.generateCode(FocusImpl.scala:7)
at monocle.internal.focus.FocusImpl.$anonfun$3$$anonfun$2(FocusImpl.scala:21)
at scala.util.Either.flatMap(Either.scala:352)
at monocle.internal.focus.FocusImpl.$anonfun$1(FocusImpl.scala:22)
at scala.util.Either.flatMap(Either.scala:352)
at monocle.internal.focus.FocusImpl.run(FocusImpl.scala:22)
at monocle.internal.focus.FocusImpl$.apply(FocusImpl.scala:33)
at monocle.internal.focus.AppliedFocusImpl$.apply(AppliedFocusImpl.scala:13)
Ken Scambler commented
This is actually related to Focus
not handling existential types gracefully, see #1201
Ken Scambler commented
case class Foo[T](content: Map[String, Foo[?]])
given Index[Foo[?], String, Foo[?]] = ...
Focus[Foo[?]](_.index("abc")) // Can't resolve the given Index instance
NTPape commented
I tried to but could not reproduce the issue from the opening post. Here is also a somewhat minimized version:
import java.time.Instant
import monocle.Focus
import monocle.Focus.focus
import monocle.function.Index
enum LDP:
case Container(content: Map[String, LDP], created: Instant = Instant.now)
case TextResource(content: String, created: Instant = Instant.now)
end LDP
import LDP._
given Index[LDP, String, LDP] =
Index(key => Focus[LDP](_.as[Container].content.index(key)))
given [S, I](using Index[S, I, S]): Index[S, List[I], S] =
Index {
case Nil => Focus[S]()
case key :: keys => Focus[S](_.index(key).index(keys))
}
val container = Container(Map("foo" -> Container(Map("bar" -> TextResource("banana")))))
container.focus(_.index(List("foo", "bar")).as[TextResource]).getOption