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?