unisonweb-org
unisonweb-org copied to clipboard
Error in the stream example of the abilities section
While reading the Abilities in Unison section, I tried to run the following example:
structural ability Stream e where
emit : e ->{Stream e} ()
-- equivalently
-- emit : e -> ()
Stream.range : Nat ->{} Nat ->{Stream Nat} ()
Stream.range n m =
if n >= m then ()
else
emit n
Stream.range (n + 1) m
However, I got the following error
The else clause of an if expression needs to
have the same type as the then clause.
Here, one is: Unit
and another is: Unit ->{Stream Nat} Unit
8 | if n >= m then ()
9 | else
10 | emit n
11 | Stream.range (n + 1) m
From the error message, I figured out I can replace the last line of the range definition by
Stream.range (n + 1) m ()
but this seems weird to me.
In case this is helpful, I am running release/M2j (built on 2021-10-07)
.
@maxtremblay for me (also on release/M2j) I can't reproduce this locally , but I suspect that I know what's going on.
Do you have all of this code within the same scratch file and are adding it all at once? When I do this it works as expected.
But what I think is happening is that your else clause is somehow picking up .base.Stream.range
, which is defined as:
.base.Stream.range : Nat -> Nat -> '{Stream Nat} ()
.base.Stream.range n m _ = Stream.range! n m
This would explain why it's expecting you to force the delayed thunk with ()
. What isn't clear to me is why it would pick up the Stream.range
from base
instead of the one that you are declaring. If you are able to create a transcript that reproduces this issue, that would be very helpful!
@maxtremblay thank you! I now see the behavior that you were talking about.
If I remove the use .base
then it works just fine. But the Stream.range
that's being defined should be prioritized over the one coming from .base
. So this does seem like a bug, and worse, one that users can run into while going through the intro docs. @pchiusano or @runarorama do either of you know what's going on here?