Are sum types and types classes supposed to implement the same interface? Eg. .[], .call methods.
If yes, does this apply also to sum structs and structs classes? Because, sum structs classes does not have .new class meth as struct classes have.
Are sum types and types classes supposed to implement the same interface? Eg. .[], .call methods.
If yes, does this apply also to sum structs and structs classes? Because, sum structs classes does not have .new class meth as struct classes have.
What do you mean by “sum structs classes”?
From dry-rb - dry-struct v1.0 - Introduction
“Struct classes quack like dry-types, which means you can use them in hash schemas, as array members or sum them”.
I will provide an example shortly.
“Summing” structs gives you a type, not a class/struct, there’s no .new
method, it’s not part of the type API. You can .[]
or .call
.
Yes, that is, but below I have an usecase which highlights a possible API inconsistency. I think from a client code perspective, struct classes and sum structs classes make more sense to be interchangeable. If this aspect is not important, but mapping a relation result to a sum struct is desired, then Relation#map_to
needs to use .call
or .[]
. What do you think?
class Movie < Dry::Struct
attribute :type, Types.Value('movie')
attribute :title, Types::String
end
class Episode < Dry::Struct
attribute :type, Types.Value('episode')
attribute :title, Types::String
attribute :number, Types::Integer
end
VOD = Movie | Episode
class VODRepo < Repository[:vods]
def all
root.map_to(VOD).to_a # => NoMethodError: undefined method `new' for #<Dry::Struct::Sum:0x00007fe53b9deae0>
end
end
Hi! I also ran into something similar, but I used .[]
method.
All over my codebase I use .new
for instantiating structs, but at some point I needed a sum struct:
class UserBase < Dry::Struct
attribute :id, Types::String
end
class ActiveUser < UserBase
attribute :name, Types::String
end
class BannedUser < UserBase
attribute :name, Types::String
attribute :reason, Types::String
end
class DeletedUser < UserBase
attribute :deleted_at, Types::Time
end
User = ActiveUser | BannedUser | DeletedUser
Somewhere else I use User
class like any other struct. To be consistent with which method to use to instantiate the structs, I have to use .new
, which is missing. I like to be consistent, but I have to change a lot of parts to use .[]
, so I sticked with .[]
only for instantiating User
s