Trex illegal? overlapping instances for derived classes -- is this intended?

Anthony Clayden <[email protected]> Tue, 20 Sep 2022 12:59:18 +1200
Newsgroups gmane.comp.lang.haskell.hugs.bugs
Message-ID <CABU_mxjzd3Af-dMGtH1x+Ts02Lw=GtxGTAMBEoAD423_CM9bpQ@mail.gmail.com>
--===============3996401006396074084==
Content-Type: multipart/alternative; boundary="000000000000102c9305e9115713"

--000000000000102c9305e9115713
Content-Type: text/plain; charset="UTF-8"

For derived instances I'm getting decls that aren't allowed if I try to put
them explicitly. They're rejected as overlapping, and in no
substitution ordering.

>    import Hugs.Trex
>
>    type UserId = Int
>    type EventId = Int
>
>    data Message
>      = SendChat (Rec ( message :: String,  user :: UserId ))
>      | Signup   (Rec ( eventId :: EventId, user :: UserId ))
>      deriving (Eq)
>

There's an `instance Eq Message` -- fine.

From Hugs.Trex I get (and these are fine)

>    instance EqRecRow a => Eq (Rec a)                -- pass through to a
specialised class
>    instance EqRecRow EmptyRow

These are generated by the `deriving`; note they're not specialised to the
field's type, nor for rows with combinations of labels:

>      instance (Eq a, b\eventId, EqRecRow b) => EqRecRow (eventId :: a | b)
>      instance (Eq a, b\user, EqRecRow b) => EqRecRow (user :: a | b)
>      instance (Eq a, b\message, EqRecRow b) => EqRecRow (message :: a | b)

Not specialising and not combining labels makes sense: then no clash if I
also had:

>    data Probe a b c
>      = MkProbe (Rec (user :: a, message :: b, eventId :: c))
>      deriving (Eq)

But those generated instances for `EqRecRow` overlap in no substitution
ordering -- as Hugs tells me if I try to declare them explicitly. How does
a wanted for `(MkProbe x) == (MkProbe y)` resolve to the wanted instances?
There's no preference ordering -- or is there?

Precisely because it's Trex where records are considered isomorphic up to
permutation of labels; and because each instance has an `EqRecRow b`
constraint for the rest of the row; it doesn't matter how Hugs resolves the
wanted to the instances: it'll get to the same answer. But I don't see how
this fits with Hugs usual approach for overlaps.

AntC

--000000000000102c9305e9115713
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">For derived instances I&#39;m getting decls=C2=A0that aren=
&#39;t allowed if I try to put them explicitly. They&#39;re rejected as ove=
rlapping, and in no substitution=C2=A0ordering.<div><br></div><div>&gt;=C2=
=A0 =C2=A0 import Hugs.Trex<br>&gt;=C2=A0 =C2=A0=C2=A0<br>&gt;=C2=A0 =C2=A0=
 type UserId =3D Int<br>&gt;=C2=A0 =C2=A0 type EventId =3D Int<br>&gt;=C2=
=A0 =C2=A0=C2=A0<br>&gt;=C2=A0 =C2=A0 data Message <br>&gt;=C2=A0 =C2=A0 =
=C2=A0 =3D SendChat (Rec ( message :: String, =C2=A0user :: UserId ))<br>&g=
t;=C2=A0 =C2=A0 =C2=A0 | Signup =C2=A0 (Rec ( eventId :: EventId, user :: U=
serId ))<br>&gt;=C2=A0 =C2=A0 =C2=A0 deriving (Eq)<br></div><div>&gt;</div>=
<div><br></div><div>There&#39;s an `instance Eq Message` -- fine.</div><div=
><br></div><div>From Hugs.Trex=C2=A0I get (and these are fine)</div><div><b=
r></div><div>&gt;=C2=A0 =C2=A0=C2=A0instance EqRecRow a =3D&gt; Eq (Rec a)=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 -- pass through to =
a specialised class</div><div>&gt;=C2=A0 =C2=A0=C2=A0instance EqRecRow Empt=
yRow</div><div><br></div><div>These are generated by the `deriving`; note t=
hey&#39;re not specialised to the field&#39;s type, nor for rows with combi=
nations of labels:</div><div><br></div><div>&gt;=C2=A0 =C2=A0 =C2=A0 instan=
ce (Eq a, b\eventId, EqRecRow b) =3D&gt; EqRecRow (eventId :: a | b)</div>&=
gt;=C2=A0 =C2=A0 =C2=A0 instance (Eq a, b\user, EqRecRow b) =3D&gt; EqRecRo=
w (user :: a | b)<br>&gt;=C2=A0 =C2=A0 =C2=A0 instance (Eq a, b\message, Eq=
RecRow b) =3D&gt; EqRecRow (message :: a | b)<div><br></div><div>Not specia=
lising and not combining labels makes sense: then no clash if I also had:</=
div><div><br></div><div>&gt;=C2=A0 =C2=A0 data Probe a b c<br>&gt;=C2=A0 =
=C2=A0 =C2=A0 =3D MkProbe (Rec (user :: a, message :: b, eventId :: c))<br>=
&gt;=C2=A0 =C2=A0 =C2=A0 deriving (Eq)=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0<br><br>But those generated instances for `EqRecRow` overlap i=
n no substitution ordering -- as Hugs tells me if I try to declare them exp=
licitly. How does a wanted for `(MkProbe x) =3D=3D (MkProbe y)` resolve to =
the wanted instances? There&#39;s no preference ordering -- or is there?</d=
iv><div><br></div><div>Precisely because it&#39;s Trex where records are co=
nsidered isomorphic up to permutation of labels; and because each instance =
has an `EqRecRow b` constraint for the rest of the row; it doesn&#39;t matt=
er how Hugs resolves the wanted to the instances: it&#39;ll get to the same=
 answer. But I don&#39;t see how this fits with Hugs usual approach for ove=
rlaps.</div><div><br></div><div>AntC<br><div><br></div></div></div>

--000000000000102c9305e9115713--

--===============3996401006396074084==
Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: base64
Content-Disposition: inline

X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX18KSHVncy1CdWdz
IG1haWxpbmcgbGlzdApIdWdzLUJ1Z3NAaGFza2VsbC5vcmcKaHR0cDovL21haWwuaGFza2VsbC5v
cmcvY2dpLWJpbi9tYWlsbWFuL2xpc3RpbmZvL2h1Z3MtYnVncw==

--===============3996401006396074084==--