[Hugs-users] Hugs/Trex and Overlapping Instances and FunDeps

Anthony Clayden anthony.d.clayden at gmail.com
Tue Sep 27 06:26:16 UTC 2022


I decided this could usefully be a feature, rather than a bug:
https://mail.haskell.org/pipermail/hugs-bugs/2022-September/001929.html

So I meshed it with work-in-progress on overlaps; and on allowing instances
inconsistent with FunDeps providing an overlap is strictly more specific;
and in looking to FunDep's determining positions only for detecting
overlap. So this now is accepted (`trexRemv` returns its first argument,
removing any fields whose labels are common with its second arg):


>
>    import Hugs.Trex
>
>    class TrexRemv r1 r2 rr  | r1 r2 -> rr  where
>        trexRemv :: Rec r1 -> Rec r2 -> Rec rr
>
>    instance TrexRemv EmptyRow r2 EmptyRow  where
>        trexRemv _empty _r2 = emptyRec
>
>    instance (r1'\x, r2'\x, TrexRemv r1' ( x :: _b | r2') rr', rr'\x )
>             => TrexRemv ( x :: a | r1') ( x :: _b | r2') rr'
>      where
>        trexRemv ( x = x | r1') r2 = trexRemv r1' r2
>
>    instance (r1'\x, r2\x, TrexRemv r1' r2 rr', rr'\x )
>             => TrexRemv ( x :: a | r1') r2 ( x :: a | rr' )
>      where
>        trexRemv ( x = x | r1') r2 = ( x = x | trexRemv r1' r2 )
>
>    instance (r1'\y, r2'\y, TrexRemv r1' ( y :: _b | r2') rr', rr'\y )
>             => TrexRemv ( y :: a | r1') ( y :: _b | r2') rr'
>      where
>        trexRemv ( y = y | r1') r2 = trexRemv r1' r2
>
>    instance (r1'\y, r2\y, TrexRemv r1' r2 rr', rr'\y )
>             => TrexRemv ( y :: a | r1') r2 ( y :: a | rr' )
>      where
>        trexRemv ( y = y | r1') r2 = ( y = y | trexRemv r1' r2 )
>


For each specific label, the instance heads overall are in no substitution
ordering -- because the label appears in the result just in case it
_doesn't_ appear in the second arg. The new rule is to consider only the
argument (first two) positions.

For each distinct label, the heads unify: the common instance has both
labels. The new rule is that if heads differ in having distinct labels in
corresponding positions, treat them as apart. (Or equivalently treat them
as overlapping in strict alphabetic order of labels. So you can write
instances in any sequence; they'll get loaded to alpha seq.)

As I said in that maybe-bug report


>>
>> 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
>>

[s/EqRecRow/TrexRemv/]


Similar to `remv` there's classes for `proj`(ect) and `app`(end) of rows
with distinct labels, needing these overlap rules.

So along with the Trex syntax for rows, I now have an expressively complete
set of operations. Nice-to-have would be generating these instances
on-the-fly -- as Hugs does for `Eq, Show`. That looks hard.

AntC
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/hugs-users/attachments/20220927/e0106183/attachment.html>


More information about the Hugs-Users mailing list