Search code examples
scalagenerics

Scala - generic method parameter that must extend multiple base type


I would like to have a method with a parameter that implements 2 interfaces, an example could be seen following:

  def autoClose[T <: AutoCloseable, A](closeable: T)(cb: T => A): A = {
    try {
      cb(closeable)
    } finally {
      closeable.close()
    }
  }

  def autoFlush[T <: Flushable, A](flushable: T)(cb: T => A): A = {
    try {
      cb(flushable)
    } finally {
      flushable.flush()
    }
  }

It would logical to have a method like:

  def autoFlushClose[T <: Flushable <: AutoCloseable, A](value: T)(cb: T => A): A = {
    autoClose(value) { value =>
      autoFlush(value)(cb)
    }
  }

How do I define that T type?


Solution

  • Use the compound types:

    def autoFlushClose[T <: Flushable with AutoCloseable, A](
        value: T
    )(cb: T => A): A = {
      autoClose(value) { value =>
        autoFlush(value)(cb)
      }
    }
    

    Or Scala 3 version:

    def autoFlushClose[T <: Flushable & AutoCloseable, A](
        value: T
    )(cb: T => A): A = {
      autoClose(value) { value =>
        autoFlush(value)(cb)
      }
    }