Unapply seems to fail on Cofree
clayrat opened this issue · comments
Alex Gryzlov commented
Consider this function (adapted from https://jtobin.io/time-traveling-recursion):
def oddIndices[A]: List[A] => List[A] =
scheme.zoo.histo[ListF[A, ?], List[A], List[A]](
CVAlgebra[ListF[A, ?], List[A]] {
case NilF => Nil
case ConsF(h, _ :< NilF) => List(h)
case ConsF(h, _ :< ConsF(_, t :< _)) => h :: t
}
)
This fails to compile with the following error (corresponds to the ConsF(h, _ :< NilF)
case):
Error:(21, 28) pattern type is incompatible with expected type;
found : qq.droste.data.list.NilF.type
required: F[qq.droste.data.Cofree[F,A]] forSome { type A; type F[_]; type F[_]; type A }
case ConsF(h, _ :< NilF) => List(h)
Apparently it can't figure out that F
is ListF[A, ?]
here? A workaround is to unwrap manually:
def oddIndices[A]: List[A] => List[A] =
scheme.zoo.histo[ListF[A, ?], List[A], List[A]](
CVAlgebra[ListF[A, ?], List[A]] {
case NilF => Nil
case ConsF(h, coa) => Cofree.un[ListF[A, ?], List[A]](coa) match {
case (_, NilF) => List(h)
case (_, ConsF(_, coa2)) => h :: Cofree.un[ListF[A, ?], List[A]](coa2)._1
}
}
)
Andy Scott commented
I'm wondering if this instead has to do with the typer's inability to widen NilF (extends ListF[Nothing, Nothing]
) to ListF[A, ?]
.
What if we redefine the top level NilF as:
package list
// ...
object `package` { // aka package object `list`
def NilF[A, B]: ListF[A, B] = ListF.NilF
}
// ...
object ListF {
// current NilF moved into a narrower scope
case object NilF extends ListF[Nothing, Nothing]
}
We might also have to add an additional companion for the new top level NilF, along with some boilerplate methods.