<div dir="auto">I'm trying to write a polymorphic/generic Trex record update method/class, so I can go</div><div dir="auto"><br></div><div dir="auto">> ... setTrex #y 7 r ...</div><div dir="auto"><br></div><div dir="auto">That is: use #y to index into record `r`; return `r` with its `y` field set to 7. Then it's using #y as a term-level proxy embedding the label, not as an accessor function.</div><div dir="auto">(If `r` does not contain a `y` field, that's a type error.)</div><div dir="auto">This is potentially a type-changing update. (But I think that's not relevant to the strangeness.)</div><div dir="auto"><br></div><div dir="auto">So this is mimicking GHC's `SetField` class or Lenses. I'll use Lens-like nomenclature.</div><div dir="auto"><br></div><div dir="auto">> import Hugs.Trex</div><div dir="auto">></div><div dir="auto">> class SetTrex s t a b  | s b -> t, s -> a  where</div><div dir="auto">>   setTrex :: (Rec s -> a) -> b -> Rec s -> Rec t</div><div dir="auto">></div><div dir="auto">> instance r'\y => SetTrex (y :: a | r') (y :: b | r') a b  where</div><div dir="auto">>   setTrex _hashy y (y = _y | rho') = (y = y | rho')</div><div dir="auto"><br></div><div dir="auto">Tediously, this will need an instance for each possible label name.</div><div dir="auto"><br></div><div dir="auto">Tests</div><div dir="auto"><br></div><div dir="auto">> setTrex #y 7 (y = 5)             -- returns (y = 7) -- OK</div><div dir="auto">> setTrex #y 7 (z = 'z', y = 5)     -- returns (y = y, z = 'z')  -- OK</div><div dir="auto">> setTrex #y 7 (x = 'x', y = 5)</div><div dir="auto"><br></div><div dir="auto"><p style="margin:0px;font-size:12px;line-height:normal;font-family:Helvetica"><span style="font-size:12pt">ERROR - Constraints are not consistent with functional dependency</span></p>
<p style="margin:0px;font-size:12px;line-height:normal;font-family:Helvetica"><span style="font-size:12pt">*** Constraint       : SetTrex (x :: Char, y :: a) (y :: b, x :: Char, y :: b, x :: Char) a b</span></p>
<p style="margin:0px;font-size:12px;line-height:normal;font-family:Helvetica"><span style="font-size:12pt">*** And constraint   : SetTrex (y :: a, x :: Char) (y :: b, x :: a) a b</span></p>
<p style="margin:0px;font-size:12px;line-height:normal;font-family:Helvetica"><span style="font-size:12pt">*** For class        : SetTrex a b c d</span></p>
<p style="margin:0px;font-size:12px;line-height:normal;font-family:Helvetica"><span style="font-size:12pt">*** Break dependency : d a -> b</span></p><p style="margin:0px;font-size:12px;line-height:normal;font-family:Helvetica"><span style="font-size:12pt"><br></span></p><p style="margin:0px;font-size:12px;line-height:normal;font-family:Helvetica"><span style="font-size:12pt">(If I give an explicit signature for the result, the error goes away.)</span></p><p style="margin:0px;font-size:12px;line-height:normal;font-family:Helvetica"><span style="font-size:12pt"><br></span></p><p style="margin:0px;font-size:12px;line-height:normal;font-family:Helvetica"><span style="font-size:12pt">Notice </span></p><p style="margin:0px;font-size:12px;line-height:normal;font-family:Helvetica"><span style="font-size:12pt">* the complaint is about **constraints** not consistent</span></p><p style="margin:0px;font-size:12px;line-height:normal;font-family:Helvetica"><span style="font-size:12pt">  so Hugs is generating constraints from the input expression</span></p><p style="margin:0px;font-size:12px;line-height:normal;font-family:Helvetica"><span style="font-size:12pt">  and comparing to the constraint arising from the method's type</span></p><p style="margin:0px;font-size:12px;line-height:normal;font-family:Helvetica"><span style="font-size:12pt"><br></span></p><p style="margin:0px;font-size:12px;line-height:normal;font-family:Helvetica"><span style="font-size:12pt">* the reversal in order of appearance of labels in the records.</span></p><p style="margin:0px;font-size:12px;line-height:normal;font-family:Helvetica"><span style="font-size:12pt"><br></span></p><p style="margin:0px;font-size:12px;line-height:normal;font-family:Helvetica"><span style="font-size:12pt">* but chiefly, the weird doubling-up of the record fields in the first Constraint.</span></p><p style="margin:0px;font-size:12px;line-height:normal;font-family:Helvetica"><span style="font-size:12pt"><br></span></p><p style="margin:0px;font-size:12px;line-height:normal;font-family:Helvetica"><span style="font-size:12pt">If I try to update `y` in a record with 3 labels `x`, `y`, `z`, I get the same error, with even more puzzling details.</span></p><p style="margin:0px;font-size:12px;line-height:normal;font-family:Helvetica"><span style="font-size:12pt"><br></span></p><p style="margin:0px;font-size:12px;line-height:normal;font-family:Helvetica"><span style="font-size:12pt">( The type vars used in the 'For class .../dependency ...' are distinct from the type vars in the constraints. That's usual Hugs perplexity.)</span></p><div dir="auto"><span style="font-size:12pt"><br></span></div><div dir="auto"><span style="font-size:12pt">If I declare a direct function to achieve the same thing, with signature</span></div><div dir="auto"><span style="font-size:12pt"><br></span></div><div dir="auto"><span style="font-size:12pt">> </span><span style="font-size:12pt;font-family:Helvetica">ss :: r'\y => (Rec (y :: a | r') -> a) -> b -> Rec (y :: a | r') -> Rec (y :: b | r')</span></div><div dir="auto"><span style="font-size:12pt;font-family:Helvetica">> </span><span style="font-size:12pt;font-family:Helvetica">ss _hashy y (y = _y | rho') = (y = y | rho') </span><span style="font-size:12pt;font-family:Helvetica"> </span></div><div dir="auto"><span style="font-size:12pt"><br></span></div><div dir="auto"><span style="font-size:12pt">all works fine. (But of course there's no FunDeps to worry about being consistent with.)</span></div><div dir="auto"><span style="font-size:12pt"><br></span></div><div dir="auto"><span style="font-size:12pt"><br></span></div><div dir="auto"><span style="font-size:12pt">AntC</span></div></div>