Stream: beginners

Topic: Opaque types - Type "prefix"


view this post on Zulip Patrick Wierer (Jan 01 2025 at 17:35):

Hey,
when working with opaque types, I constantly seem to get it wrong when to "prefix" my def with the actual type, e.g. when passing it to another function that expects such a type.

Example:

A := {
    input: List U8
}

new : {} -> A
new = \{} -> @A { input: [] }

someFunc : A -> Result {} _
someFunc = \@A a ->
    a2 = anotherFunc (@A a) # only works with @A
    a3 = anotherFunc a2 # only works without @A
    Ok ({})

anotherFunc : A -> A
anotherFunc = \@A a ->
    @A a # only works with @A

Is it maybe just me not understanding when to explicitly prefix the def, or is this currently a known "issue"?
Anyway, I am very new to Roc, so my limited understanding and experience with Roc might be very well the root cause.

view this post on Zulip Ayaz Hafiz (Jan 01 2025 at 17:40):

Sorry to hear that it's been confusing when to prefix the type. If it helps, the type of @A a and a itself are different. In this case @A a is the entire opaque type A. a is the type "inside" A, so { input: List U8 } in your example. To pass { input: List U8 } to anotherFunc, it must first be wrapped in the A. But anotherFunc returns an A, so you don't need to wrap it again when calling a3 = anotherFunc a2.

view this post on Zulip Patrick Wierer (Jan 01 2025 at 17:47):

No worries, it's the normal process with everything new. Just takes time to internalize things :blush:
Thanks for the explanation, it definitely makes sense to me now.
So it seems the argument @A a from someFunc is actually unwrapped, which explains my confusion as to why I would need to wrap it again when calling anotherFunc the first time.

view this post on Zulip Sam Mohr (Jan 01 2025 at 17:50):

Yep!


Last updated: Jul 06 2025 at 12:14 UTC