Right now Task.await is a function over Tasks. But consider the proposed new model of Task effects, which allows composing effects arbitrarily (https://gist.github.com/ayazhafiz/4fbb9cdc284ba5cdfabb53e0c39a7b4d):
interface A exposes [main] imports []
# Task.roc
Task v op := (v -> op) -> op
await : Task a op, (a -> Task b op) -> Task b op
await = \@Task fromResult, next ->
@Task \continue ->
fromResult \result ->
@Task inner = next result
inner continue
# StdinEffect.roc
OpIn a b : [
StdinLine (Str -> OpIn a b),
Done a,
]b
# Stdin.roc
lineIn : Task Str (OpIn * *)
lineIn = @Task \toNext -> StdinLine \s -> (toNext s)
# StdoutEffect.roc
OpOut a b : [
StdoutLine Str ({} -> OpOut a b),
Done a,
]b
# Stdout.roc
lineOut : Str -> Task {} (OpOut * *)
lineOut = \s -> @Task \toNext -> StdoutLine s \{} -> (toNext {})
# Platform
# really, we want a syntax like [Done a](OpIn a)(OpOut a) here
Op a : [
StdinLine (Str -> Op a),
StdoutLine Str ({} -> Op a),
Done a,
]
main : Task {} (Op *)
main =
lineIn
|> await \s -> lineOut s
In this model, we can. compose StdoutLine/StdinLine into a single effect despite declaring them separately, and moreover the definition of the StdinLine/StdoutLine effects do not depend at all on Task.
Is there any way to express Await as an effect in the same way, as a tag in an Op type? I feel like this must be possible, but unfortunately I do not see a way to do so immediately.
That is, have await be defined via an Await tag in an Op type that can be evaluated by a platform, in the same way StdinLine/StdoutLine are, rather than a Task -> Task transformation function in Roc
Could it be done with something like: Await ((OpIn x b), (x -> OpIn a b)). The platform would run OpIn x b to completion, then used the returned x to continue the x -> OpIn a b closure.
I guess that wouldn't work cause I making a type variable out of nowhere. Not sure how you can specific the intermediate await type
Right. I guess we could use Erased there so that the type variable can disappear, but then the task needs to be boxed
I wonder if there's a way to do it without type erasure
Last updated: Jun 16 2026 at 16:19 UTC