Hey all, can anyone help me figuring out how to do something with Generics?

Basically I have:

classConstruct(Norma)=>ConstructNormawheretypeNormatoNorm::a->NormafromNorm::Norma->ainstanceConstructNorm()wheretypeNorm()=()toNorm=Prelude.idfromNorm=Prelude.idinstance(ConstructNorma,ConstructNormb)=>ConstructNorm(Eitherab)wheretypeNorm(Eitherab)=Either(Norma)(Normb)toNorm=either(Left.toNorm)(Right.toNorm)fromNorm=either(Left.fromNorm)(Right.fromNorm)-- Instance for other data types can be obtained mechanically using GenericsinstanceConstructNormBoolwheretypeNormBool=Either()()toNorm=bool(Left())(Right())fromNorm=either(constFalse)(constTrue)

And I want to have an instance for arbitrary Generic types.

I already have type families that to this at the type level:

Yes that's the idea. If you see my type families what I do is I count the cardinality of the type with Count and then use FromNat to generate the Either type

Hey @Sandy Maguire, I tried those but they did not quite fit my needs :confused: they work from/to a Generic Representation only. I couldn't have, for example f :: Ordering -> Either () (Either () ()) / g :: Either () (Either () ()) -> Ordering

Hey all, can anyone help me figuring out how to do something with Generics?

Basically I have:

And I want to have an instance for arbitrary Generic types.

I already have type families that to this at the type level:

Is there any easy way to this at the term level?

So for every type, you want it's cardinality and "canonical representation" using

`Either`

and`(,)`

?For every type I want an isomorphism with respect to its cardinality in a "canonical representation" using only

`Either`

What would be the representation of

`Int`

?I have this so far:

TheMatten said:

Do not bother with this edge case

But if you want it really bad then it should be equivalent to

`FromNat 9223372036854775807`

I guessOkay, so

`data A = B | C | D | ..`

goes to`Either () (Either () (Either () ..))`

?What about fields?

I dont think a type can be

`Bounded`

if it has fieldsOr at least GHC cannot derive an instance to it, so it's off the record

Ah, I missed

`Bounded`

requirement - okay, then you simply want to match`V1`

,`U1`

,`:+:`

and`M1`

I guess?Keep in mind though that

`Rep`

tries to keep branches similarly long and thus doesn't have nice, one-side-biased shapeI want

`:*:`

too :frown: that's one of the hard parts..But

`:*:`

only appears with fields, doesn't it?I don't think so! image.png

Ah, you want tuples then?

Tuple is just constructor with fields

But I want to transform a tuple into Eithers!

How do you do that, even in theory? You need some notion of a product - unless you go

`n * a = a + a + ... + a + a`

(n times)Yes that's the idea. If you see my type families what I do is I count the cardinality of the type with

`Count`

and then use`FromNat`

to generate the`Either`

typeI think I did it!

Since

`Count a ~ Count (Normalize a)`

, under this restrictions this isomorphism is correct!you already have these functions; they're just

`to`

and`from`

Hey @Sandy Maguire, I tried those but they did not quite fit my needs :confused: they work from/to a Generic Representation only. I couldn't have, for example

`f :: Ordering -> Either () (Either () ())`

/`g :: Either () (Either () ()) -> Ordering`