"isomorphic" datastructures

Hi,

Here is a X/Y problem

Problem X:
I handle data structures which are a nesting of Tuples, NamedTuples and SVector, of various Reals.

I want to create a function isomorph(a,b) that is equivalent to typeof(a)==typeof(b) except that it must also return true if the concrete Real types are different. For example a NTuple{3,Float64} and a NTuple{3,Int64} are, I say, isomorph.

I want to implement it in the form of a set of methods, recursing down the datastructure.

Problem Y
I decide to create methods that operate on DataTypes, like isomorph(typeof(a),typeof(b)) instead of variables because

  1. otherwise I do not sea how to compare two SVectors of length 0.
  2. this emphasizes the intention of having this code run at compile time

I start with

isomorph(::Type{<:Any }         ,::Type{<:Any }) = false # in doubt, no
isomorph(::Type{<:Real}         ,::Type{<:Real}) = true

So the method for SVector is simply

isomorph(::Type{<:SArray{S,Ta}},::Type{<:SArray{S,Tb}}) where{S,Ta,Tb} = 
                     isomorph(Ta,Tb)

For Tuples, I use a hack (ugh! Julia internal) to get the types of the Tuple components: Ta.types, as in

isomorph(Ta::Type{<:Tuple},Tb::Type{<:Tuple}) = length(Ta.types) == length(Tb.types) && all(isomorph.(Ta.types,Tb.types))

The same Ta.types works for NameTuples, but how to I get the keys from the type?

:slightly_smiling_face:

fieldnames(Ta) :grin:

You can say

julia> fieldtypes(Tuple{Bool,Char})
(Bool, Char)
1 Like

You realize that “XY problem” refers to a question where you have mis-identified the root problem, right?

I handle data structures which are a nesting of Tuples, NamedTuples and SVector, of various Reals. I want to create a function isomorph(a,b) that is equivalent to typeof(a)==typeof(b) except that it must also return true if the concrete Real types are different.

What is the underlying problem that you are trying to solve that requires this?