Stream: beginners

Topic: Puzzling type error


view this post on Zulip Anne Archibald (Feb 03 2024 at 18:19):

I am trying to build "generators", functions that can use a Task-like syntax to yield values and then resume when another value is requested. They work, but as I try to build one of the useful operators on them, I am running into a type error that I can't understand:

This yieldFrom call produces:

    [
        Stop,
        YieldValue a ({} -> YieldValue a),
    ] as *

But all the previous branches have type:

    [
        Stop,
        YieldValue s ({} -> YieldValue a),
    ]b

All branches of a when must have the same type!

────────────────────────────────────────────────────────────────────────────────

1 error and 4 warnings found in 30 ms

The code required to explain all this is a bit long: https://github.com/aarchiba/roc-experiments/blob/main/Stream.roc#L328

But I don't understand the difference between these two types, or why the types in this code shouldn't work. Specifically, they seem to differ in that one has a "b" appended, and the other has an "as *" appended. I don't understand what either of these mean. Perhaps the error message could be clearer?

view this post on Zulip Brendan Hansknecht (Feb 03 2024 at 18:58):

I think the important part is YieldValue a vs YieldValue s

view this post on Zulip Kiryl Dziamura (Feb 03 2024 at 19:04):

Speaking of types puzzles, I recently ran into this mystery :grinning_face_with_smiling_eyes:

telegram-cloud-photo-size-2-5325936614897210857-y.jpg

I'll try to localize the problem, but it's gone when I removed type annotation from the function allowing type system to infer types

view this post on Zulip Brendan Hansknecht (Feb 03 2024 at 19:05):

Definitely need more context on that one, but looks like a bug (or at least a missing constraint that isn't being printed)

view this post on Zulip Anne Archibald (Feb 03 2024 at 20:13):

Brendan Hansknecht said:

I think the important part is YieldValue a vs YieldValue s

Well spotted, but for the life of me I can't figure out why roc is inferring that type.

view this post on Zulip Brendan Hansknecht (Feb 03 2024 at 20:49):

I was adding more type annotions and I think these two may be hitting the same underlying issue:

Something is off with the body of the yieldFn definition:

332│              yieldFn : {} -> YieldValue a
333│              yieldFn = \{} -> yieldFrom (Stream next s2)
                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^

This yieldFrom call produces:

    YieldValue a

But the type annotation on yieldFn says it should be:

    YieldValue a

view this post on Zulip Brendan Hansknecht (Feb 03 2024 at 20:49):

My guess....lambdasets.

view this post on Zulip Brendan Hansknecht (Feb 03 2024 at 20:50):

The compiler is seeing the values as two different types cause it is failing to unify their lambdasets.

view this post on Zulip Brendan Hansknecht (Feb 03 2024 at 20:50):

but yeah, compiler bugs


Last updated: Jul 05 2025 at 12:14 UTC