Hey so I want to create an algebraic data type in roc like this:
Student : [
Current,
Graduated
]
Current : {
name : Str,
grade : U64
}
Graduated : {
name : Str,
finalGrade : U64
}
First question, is this the right way to define my ADT?
Second question, if yes to q1, why am I getting a type mismatch on the following function?
sumStudent : (Dict Str Json), Str -> Result Student JsonErrors
sumStudent =\d, name ->
when Dict.get d "finalGrade" is
Ok (Number fg) -> Ok ({ name: name, finalGrade: fg })
_ -> when Dict.get d "grade" is
Ok (Number cg) -> Ok ({ name: name, grade: cg })
_ -> Err(FieldNotFound "found neither field")
(I basically want to return either of the sum type variants depending on if the field is a key in d
)
Thanks in advance!
It's been awhile since I've written any Roc, but I think the problem here is that Roc doesn't have untagged unions. Student
would need to be tagged union instead. So I think you probably want something like this:
Student : [
Current {
name : Str,
grade : U64
},
Graduated {
name : Str,
finalGrade : U64
}
]
Also here's the relevant section of the tutorial which covers tags with payloads: https://www.roc-lang.org/tutorial#tags-with-payloads
Hope that helps!
Ahhhh I tried
Student : [
Current : {
name : Str,
grade : U64
},
Graduated : {
name : Str,
finalGrade : U64
}
]
at first which didn't work
managed to make this work by doing the following:
sumStudent =\d, name ->
when Dict.get d "finalGrade" is
Ok (Number fg) -> Ok (Graduated { name: name, finalGrade: fg })
_ -> when Dict.get d "grade" is
Ok (Number cg) -> Ok (Current { name: name, grade: cg })
_ -> Err(FieldNotFound "found neither field")
Thanks for your help!
nice! btw roc format
will automatically normalize indentation and spaces and such
ah nice thanks for that!
Last updated: Jul 06 2025 at 12:14 UTC