5

I am having trouble with path dependent types and pattern matching:

trait View[A]

trait Foo {
  type Bar

  def defaultBar: Bar
}
trait Baz extends Foo {
  def view(init: Bar): View[Bar]
}

trait Test {
  val foo: Foo

  def bar: foo.Bar = foo.defaultBar

  def test(): Option[View[foo.Bar]] =
    foo match {
      case b: Baz => Some(b.view(bar))
      case _ => None
    }
}

This fails because scalac doesn't identify foo with b. As a result, it only works with two casts:

      case b: Baz => Some(b.view(bar.asInstanceOf[b.Bar]).asInstanceOf[View[foo.Bar]])

Surely there must be a clean way to avoid the casts?

0__
  • 64,257
  • 16
  • 158
  • 253
  • i'm not sure, but aren't such type casts against the logic of path-dependant types? Then why not to use type projection with covariance? – 4lex1v Sep 23 '13 at 10:30
  • I cannot use projections because the basic member type is too general. That would only work if I go through the hoop of `trait Foo[F <: avoid.="" bar="" def="" defaultbar:="" f="" foo="" i="" like="" really="" to="" type="" which="" would=""> – 0__ Sep 23 '13 at 11:15
  • Are you missing some code from `Baz`? In this sample above you never define `Baz` as a type for `Bar`. Your test is matching on a `Foo` but your code never makes `Baz` a valid `Foo`. – iain Sep 23 '13 at 13:45
  • @iain `Baz` is sub-type of `Foo`. If I match `foo` and find it is an instance of `Baz`, obviously `b eq foo`. – 0__ Sep 23 '13 at 14:56

1 Answers1

0

Its not possible to do without using projections and restricting the type as defaultBar we can override it to unrelated data types

for eg

trait MyFoo extends Foo { override def defaultBar: Int }

Akhil
  • 518
  • 5
  • 12