For anyone following the Great Haskell Record Debates, is there still a proposal on the table anything like this?


data Name (s :: String) = Name

class Has (name :: String) (record :: *) (field :: *) | name record -> field where
_ getField :: Name name -> record -> field
_ setField :: Name name -> field -> record -> record

----------------

data Foo = Foo { x :: Int }
==>
data Foo = Foo Int
instance Has "x" Foo Int where
_ getField _ (Foo x) = x
_ setField _ x (Foo _) = Foo x
-- No declaration for 'x' is generated. 'x' is NOT a variable.

(r.x) ==> getField (Name :: Name "x") r
(.x) ==> getField (Name :: Name "x") -- syntactically like a section

r { x = foo } ==> setField (Name :: Name "x") foo r
({x = foo}) ==> setField (Name :: Name "x") foo -- Desugars to composition for multiple assignments
({x =}) ==> setField (Name :: Name "x") -- Only one field assignment allowed here
-- Type-changing assignment is NOT allowed for records

fun (Foo { x = pat })
==>
fun __tmp@(Foo _) | pat <- getField (Name :: Name "x") __tmp

Disadvantages:
- Compatibility is completely broken.
- Type ambiguities will be a bear, and likely require some heavyweight defaulting reform.

Still, this appeals to me in a lot of ways. In particular, the idea that record field names are not variables feels like getting something right that Haskell initially got wrong.
Shared publiclyView activity