# New notation for records?

**URL:** <https://discourse.haskell.org/t/new-notation-for-records/9663>\
**Category:** Uncategorized\
**Created:** [June 1, 2024, 8:08pm UTC](https://discourse.haskell.org/t/new-notation-for-records/9663 "2024-06-01T20:08:44Z")\
**Posts on this page:** 1\
**Showing post:** 21

<div class="post-metadata">

**Author:** ![rhendric](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/rhendric/32/2689_2.png) [@rhendric](https://discourse.haskell.org/u/rhendric)\
**Post date:** [June 3, 2024, 1:13am UTC](https://discourse.haskell.org/t/new-notation-for-records/9663/21 "2024-06-03T01:13:17Z")

</div>

> [@darkxero](#):
>
> My original intention was to see if it could be made into an extension of GHC so that the do’s desugar into plain record notation, so you don’t have to type all those brackets and nested records referring to the previous one. It wouldn’t involve lenses.

- Mom, can we add a dependency on lenses?
- We have lenses at home.

Lenses at home:

```hs
{-# LANGUAGE AllowAmbiguousTypes, BlockArguments, DuplicateRecordFields, OverloadedLabels #-}

import Control.Monad.State (State, execState, modify)
import GHC.OverloadedLabels (IsLabel(..))
import GHC.Records (HasField(..))

setField :: HasField s a b => b -> a -> a
setField = error "wait for https://gitlab.haskell.org/ghc/ghc/-/issues/16232"

instance (HasField s a b, c ~ ()) => IsLabel s (State b () -> State a c) where
  fromLabel inner = modify (setField @s =<< execState inner . getField @s)

newtype Setter a b = Setter { (.=) :: b -> State a () }

instance HasField s a b => IsLabel s (Setter a b) where
  fromLabel = Setter (modify . setField @s)

(&~) :: a -> State a () -> a
(&~) = flip execState

data Country = Country {name :: String, company :: Company} deriving Show
data Company = Company {name :: String, boss :: Employee, car :: Car} deriving Show
data Employee = Employee {name :: String, age :: Integer, empCar :: Car} deriving Show
data Car = Car {name :: String} deriving Show

f :: Integer -> Country -> Country
f i r =
  r &~ do
    #company do
        #boss do
            #age .= i
        #car do
            #name .= "new"
        #name .= "cmp"
    #name .= "ccc"

```

The [deluxe version](https://play.haskell.org/saved/W3ERhyAS) (requires 9.6+) even allows you to write:

```hs
  r &~ do
    #company do
        #"boss.age" .= i
        #"car.name" .= "new"
        #name .= "cmp"
    #name .= "ccc"

```

Of course, there is the minor downside that neither actually works yet, but at least there’s a plan for them to work at some point.

---

_[View the full topic](https://discourse.haskell.org/t/new-notation-for-records/9663)._
