Hi all,
I have come up against a use case while using SwiftData that would heavily benefit from modelling using some ADT-like structure. The most straightforward method does not work:
// does not compile!
@Model
enum ADT {
case foo(Int)
case bar(String)
}
The first thing I thought to try from there was using an empty protocol that the discriminants could conform to:
protocol ADT: Hashable {
}
@Model
final class Foo: ADT {
var date: Date
init(date: Date = Date()) {
self.date = date
}
}
But this doesn't work because any ADT
does not conform to Hashable
and therefore can't be used as the principal argument in ForEach
, which I need for my use case:
struct SomeView: View {
@Query var foos: [Foo]
var adts: [any ADT] {
foos
}
var body: some View {
// does not compile!
ForEach(adts, id: \.self) { _ in
Text("hello, world")
}
}
}
Subclassing also doesn't work because SwiftData doesn't support it.
My last resort will be a kind of manual discriminated union, which I dread having to implement for the number of mistakes I'm sure to make. So I thought to check here first—any ideas would be most welcome.
Thank you!