Тип выводит ничего в Scala - PullRequest
12 голосов
/ 31 июля 2011

Когда я пытаюсь скомпилировать небольшой пример:

trait Foo[A,B] {
  type F[_,_]
  def foo(): F[A,B]
}

class Bar[A,B] extends Foo[A,B] {
  type F[D,E] = Bar[D,E]
  def foo() = this
}

object Helper {
  def callFoo[A,B,FF <: Foo[A,B]]( f: FF ): FF#F[A,B] =
    f.foo()
}

object Run extends App {
  val x = new Bar[Int,Double]
  val y = Helper.callFoo(x)
  println( y.getClass )
}

Я получаю ошибку:

[error] src/Issue.scala:20: inferred type arguments
[Nothing,Nothing,issue.Bar[Int,Double]] do not conform to method callFoo's type
parameter bounds [A,B,FF <: issue.Foo[A,B]]
[error]       val y = Helper.callFoo(x)

По-видимому, механизм определения типа не способен выводить A и B из бара [A, B]. Тем не менее, это работает, если я передаю все типы вручную:

val y = Helper.callFoo[Int,Double,Bar[Int,Double]](x)

Есть ли способ избежать явной передачи типов?

Ответы [ 2 ]

11 голосов
/ 31 июля 2011

Вам придется изменить сигнатуру callFoo на эту:

def callFoo[A, B, FF[A, B] <: Foo[A, B]](f: FF[A, B]): FF[A, B]#F[A, B] =

Вы должны указать компилятору, что FF на самом деле является параметризованным типом.

2 голосов
/ 31 июля 2011

Будет ли работать использование типа члены вместо параметров?

trait Foo {
  type A
  type B
  type F
  def foo(): F
}

class Bar extends Foo {
  type F = Bar
  def foo() = this
}

object Helper {
  def callFoo[FF <: Foo]( f: FF ): FF#F =
    f.foo()
}

object Run extends App {
  val x = new Bar{type A=Int; type B=Double}
  val y = Helper.callFoo(x)
  println( y.getClass )
}

При использовании членов типа полезно знать, что они могут быть отображены как параметры типа с использованием уточнения, так какв ответе Майлза Сабина на: Почему эта циклическая ссылка с проекцией типа недопустима?

См. также этот недавний вопрос, который похож на ваш: Scala не может сделать правильный выводвведите аргументы

...