scala> import annotation.effects._
import annotation.effects._
scala> class E1 extends Exception
defined class E1
scala> trait Fun[A, B, E <: Exception] { def apply(a: A): B @throws[E] }
defined trait Fun
scala> def foo[E <: Exception](fun: Fun[Int, Int, E]): Int @throws[E] = fun(1)
foo: [E <: Exception](fun: Fun[Int,Int,E])Int @scala.annotation.effects.throws[E]
scala> foo(new Fun[Int, Int, Nothing] { def apply(x: Int) = x })
res1: Int @scala.annotation.effects.throws[Nothing] = 1
scala> foo(new Fun[Int, Int, E1] { def apply(x: Int) = x })
res2: Int @scala.annotation.effects.throws[Nothing] = 1
scala> foo(new Fun[Int, Int, Nothing] { def apply(x: Int) = throw new E1 })
<console>:14: error: overriding method apply in trait Fun of type (a: Int)Int @scala.annotation.effects.throws[Nothing];
method apply has incompatible type
foo(new Fun[Int, Int, Nothing] { def apply(x: Int) = throw new E1 })
^
scala> def bar = foo(new Fun[Int, Int, E1] { def apply(x: Int): Int @throws[E1] = x })
bar: Int @scala.annotation.effects.throws[Nothing]
feels like java :)
this one in fact does not seem to work: