实现抽象方法时函数类型不匹配

时间:2016-07-16 00:25:26

标签: scala function abstract traits

我是Scala的新手,不幸的是我坚持这个问题。

我在Types.Subscribe中定义了一个我想重用的函数类型,如下所示:

object Types {
  type Subscribe[T] = (T => T)
}

trait Adapter[T] {
  def subscribe: Types.Subscribe[T]
}

class IntAdapter extends Adapter[Int] {
  def map(subscribe: Types.Subscribe[Int]) = { 1 }
  def subscribe(value: Int): Int = { 2 }
}

但是,我从IntelliJ收到以下错误:

  

必须将类FooAdapter声明为abstract或实现   抽象成员'subscribe:Types.Subscribe [T]'

似乎def subscribe(value: Int): Int与函数类型(Int => Int)不匹配,这有点令人困惑。如果是这种情况,我如何定义一个我能够如上所述重用的订阅功能类型?

我尝试使用apply方法定义函数类型:

trait StreamSubscribe[T] {
  def apply(value: T): T
}

但是,我也无法使用它。

我想为subscribe方法的类型签名提供单一的事实来源,而不是在随机位置重复它。我怎样才能做到这一点?

2 个答案:

答案 0 :(得分:2)

我认为你可能会混合两个概念类函数(aka方法)和匿名函数。虽然核心都只是函数,但您无法按照自己的方式定义类函数,但可以按预期使用它。

不确定您将如何使用该功能,但我相信这正是您所寻找的......

object Types {
  type Subscribe[T] = (T => T)
}

trait Adapter[T] {
  /**
    *
    * @return a function which takes a [[T]] and returns a [[T]]
    */
  // def subscribe: Types.Subscribe[T]

  /**
    * @param value a [[T]]
    * @return a [[T]]
    */
  def subscribe(value: T): T
}

class IntAdapter extends Adapter[Int] {
  def map(subscribe: Types.Subscribe[Int]) = {
    subscribe(1)
  }

  def subscribe(value: Int): Int = {
    value + 2
  }
}

val adapter = new IntAdapter()
adapter.map(adapter.subscribe) // returns 3

答案 1 :(得分:1)

您的Adapter.subscribe是"无参数方法类型"结果为Subscribe[T],或=> Subscribe[T]=> T => T

没有什么不寻常之处,但您的IntAdapter.subscribe需要参数,Int => Int,并且不会覆盖。

你可以这样做:

scala> object X { type F[A] = A => A }
defined object X

scala> trait T[A] { def f: X.F[A] }
defined trait T

scala> class TI extends T[Int] { def fImpl(i: Int) = 2 * i ; def f = fImpl }
defined class TI

scala> new TI().f(42)
res0: Int = 84

其中fImpl变为(i: Int) => fImpl(i)

或使用符号方便:

scala> class TI extends T[Int] { def f = 2 * _ }
defined class TI