Expressing the type of attribute B as dependent on an arbitrary value of attribute A.

What might be the simplest way to express this type if it is possible? Would monads work here? Is there a better way?

    class VersionedMetadata < Dry::Struct
      attribute :version, Types::Strict::Integer

      # how do I express this?
      attribute :metadata, MetadataV1 # if version == 1
      attribute :metadata, MetadataV2 # if version == 2
      attribute :metadata, UnsupportedVersionMetadata # any other value of version

Yes I am aware that the ‘type’ attribute can allow for polymorphic construction but that isn’t quite the same as what I’m hoping to learn how to do. Would love to be able to change the type of attribute B based on arbitrary values of attribute A.

It can be encoded via

module VersionedMetadata
  class V1 < Dry::Struct
    attribute :version, Types::Strict::Integer.constrained(eql?: 1)
    attribute :metadata, MetadataV1

  class V2 < Dry::Struct
    attribute :version, Types::Strict::Integer.constrained(eql?: 2)
    attribute :metadata, MetadataV2

  class Other < Dry::Struct
    attribute :version, Types::Strict::Integer
    attribute :metadata, UnsupportedVersionMetadata

  Type = V1 | V2 | Other

Thanks, thats close to what I had tried another time, was curious to see if there were other methods. Appreciate the response!