Stream: ideas

Topic: Union and products as binary operations


view this post on Zulip Mauro Cano (Aug 16 2022 at 00:11):

I might be wildly wrong about this.
I feel like extending unions and records behave more like binary operations.
For example, User a : { username: Str, email: Str }a could be User a : { username: Str, email: Str } & a or even User a : { username: Str } & { email: Str } & a. But if I had access to this feature, I would write User : { username: Str, email: Str } and then use User & a when I want to allow a user with extra fields, so I wouldn't need two different type annotations for User and User a.
Unions could be [PageNotFound, Timeout, BadPayload Str] | a or [PageNotFound] | [Timeout] | [BadPayload Str] | a instead of [PageNotFound, Timeout, BadPayload Str]a.
In the example in roc-for-elm-programmers, I imagine the resulting type of doStuff like Filename -> Task File.Data (File.WriteErr | File.ReadErr | Http.Err). But then the rest of the example explains why we need to change the definition of File.WriteErr, etc. including a type variable in the definition and in every single usage, in order to acheive this. I also imagine that the compiler's error message could be better if it outputs File.WriteErr | File.ReadErr | Http.Err instead of File.WriteErr (File.ReadErr (Http.Err []).

view this post on Zulip Ayaz Hafiz (Aug 16 2022 at 01:43):

Extending tag unions and records indeed are binary operations. But, they are right-associative, rather than being arbitrarily composable. In your last example, File.WriteErr | File.ReadErr | Http.Err and File.WriteErr (File.ReadErr (Http.Err []) are isomorphic - the latter is basically File.WriteErr | (File.ReadErr | (Http.Err | [])).

view this post on Zulip Ayaz Hafiz (Aug 16 2022 at 01:43):

It sounds like maybe what you're trying to get it, is that the ergonomics of these types could be improved if they were instead compared by subtyping. Is that correct?

view this post on Zulip Mauro Cano (Aug 16 2022 at 21:21):

Yes I guess my first impression is that it's a bit counter-intuitive but you're right, it's still a binary operation.


Last updated: Jun 16 2026 at 16:19 UTC