0

I'm new to Scala, I'm stuck on this problem unfortunately.

I have a function type defined in Types.Subscribe that I want to reuse as follows:

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 }
}

However, I get the following error from IntelliJ:

Class FooAdapter must either be declared abstract or implement abstract member 'subscribe: Types.Subscribe[T]'

It seems that def subscribe(value: Int): Int does not match function type (Int => Int), which is a bit confusing. If that's the case, how can I define a Subscribe function type that I would be able to reuse as described above?

I tried defining the function type using the apply method:

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

However, I could not get this to work either.

I want to have a single source of truth for the type signature of the subscribe method, instead of repeating it in random places. How can I achieve that?

1
  • Your trait Adapter has def subscribe and your IntAdapter has def subscribe(value: Int). Notice any difference? Commented Jul 16, 2016 at 9:37

2 Answers 2

2

I think you might be mixing two concepts class functions (aka methods) and anonymous functions. Although at the core both are just functions you can't define a class function the way you would like but you could use it as you would expect.

Not sure exactly how you would utilize the function but I believe this is what you are looking for...

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
Sign up to request clarification or add additional context in comments.

Comments

1

Your Adapter.subscribe is a "parameterless method type" with result Subscribe[T], or => Subscribe[T] or => T => T.

Nothing unusual about that, but your IntAdapter.subscribe takes parameters, Int => Int, and doesn't override.

You can do this:

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

where fImpl becomes (i: Int) => fImpl(i).

Or using notational conveniences:

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.