Skip to content
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

Unapply seems to fail on Cofree #59

Open
clayrat opened this issue Aug 20, 2018 · 1 comment
Open

Unapply seems to fail on Cofree #59

clayrat opened this issue Aug 20, 2018 · 1 comment

Comments

@clayrat
Copy link
Contributor

clayrat commented Aug 20, 2018

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
      }
    }
  )
@andyscott
Copy link
Member

andyscott commented Sep 5, 2018

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants