Unexpected "effect is not allowed in this context" for a list of first-class functions
The following program claims that emit[<first-class function type>] is not allowed on the RHS of for, but I can't really tell why:
import stream
def applyAllAndSum(operations: List[(Int) => Unit / emit[Int] at {}], n: Int): Int / {} = sum {
with val op = for[(Int) => Unit / emit[Int] at {}] { operations.each }
// ^^^^^^^^^^^^^^^
// Possible overload: stream::each of type [A](List[A]) => Unit / { emit[A] }
// Effect emit[Int => Unit / { emit[Int] } at {}] is not allowed in this context.
(unbox op)(n)
}
Annotating the type of each as operations.each[(Int) => Unit / emit[Int] at {}] doesn't do anything...
For context, the intended application is something like:
def addOne(n: Int) = do emit(n + 1)
def monusOne(n: Int) = if (n > 0) { do emit(n - 1) }
def main() = println(applyAllAndSum([box addOne, box monusOne], 0)) // => 1
I can't even write a "monomorphized" version of for:
def myfor { stream: () => Unit / emit[(Int) => Unit / emit[Int] at {}] } { action: ((Int) => Unit / emit[Int] at {}) => Unit }: Unit / {} =
try {
stream()
// ^
// Effect emit[Int => Unit / { emit[Int] } at {}] is not allowed in this context.
} with emit[(Int) => Unit / emit[Int] at {}] { value =>
resume(action(value))
}
... is it because of the "nested" effect?
Maybe related to #813 ?
I think this is the same issue:
interface Bar {}
interface Foo[T] {
def foo(): T
}
def foo{block: => Unit / Foo[=> Unit / Bar at {}]}: Unit = ()
def main(): Unit / {} = {
foo {
val f = do foo[=> Unit / Bar at {}]()
}
}
It seems to be because of the / Bar effect set. removing it gets rid of the error. Capture sets don't trigger the error.
It happens with computation parameters too:
def foo{block: => Unit / Foo[{Bar} => Unit at {}]}: Unit = ()
def main(): Unit / {} = {
foo {
val f = do foo[{Bar} => Unit at {}]()
}
}