Trex record update strange rejection

Anthony Clayden anthony_clayden at clear.net.nz
Fri Nov 9 04:17:46 UTC 2018


I'm trying to write a polymorphic/generic Trex record update method/class,
so I can go

> ... setTrex #y 7 r ...

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.
(If `r` does not contain a `y` field, that's a type error.)
This is potentially a type-changing update. (But I think that's not
relevant to the strangeness.)

So this is mimicking GHC's `SetField` class or Lenses. I'll use Lens-like
nomenclature.

> import Hugs.Trex
>
> class SetTrex s t a b  | s b -> t, s -> a  where
>   setTrex :: (Rec s -> a) -> b -> Rec s -> Rec t
>
> instance r'\y => SetTrex (y :: a | r') (y :: b | r') a b  where
>   setTrex _hashy y (y = _y | rho') = (y = y | rho')

Tediously, this will need an instance for each possible label name.

Tests

> setTrex #y 7 (y = 5)             -- returns (y = 7) -- OK
> setTrex #y 7 (z = 'z', y = 5)     -- returns (y = y, z = 'z')  -- OK
> setTrex #y 7 (x = 'x', y = 5)

ERROR - Constraints are not consistent with functional dependency

*** Constraint       : SetTrex (x :: Char, y :: a) (y :: b, x :: Char, y ::
b, x :: Char) a b

*** And constraint   : SetTrex (y :: a, x :: Char) (y :: b, x :: a) a b

*** For class        : SetTrex a b c d

*** Break dependency : d a -> b


(If I give an explicit signature for the result, the error goes away.)


Notice

* the complaint is about **constraints** not consistent

  so Hugs is generating constraints from the input expression

  and comparing to the constraint arising from the method's type


* the reversal in order of appearance of labels in the records.


* but chiefly, the weird doubling-up of the record fields in the first
Constraint.


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.


( The type vars used in the 'For class .../dependency ...' are distinct
from the type vars in the constraints. That's usual Hugs perplexity.)

If I declare a direct function to achieve the same thing, with signature

> ss :: r'\y => (Rec (y :: a | r') -> a) -> b -> Rec (y :: a | r') -> Rec
(y :: b | r')
> ss _hashy y (y = _y | rho') = (y = y | rho')

all works fine. (But of course there's no FunDeps to worry about being
consistent with.)


AntC
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/hugs-bugs/attachments/20181109/32b64acc/attachment.html>


More information about the Hugs-Bugs mailing list