Skip to content

Precedence of record dot

Thank you @shayne-fletcher-da and all involved for your work on record dot syntax! I'm a very happy user :)

I'm not certain that the following behaviour of OverloadedRecordDot is intentional, i.e. meets the spec in the RDS proposal. If it is, sorry for the noise.

Summary

{-# LANGUAGE OverloadedRecordDot #-}
  
data Foo =
  Foo {
    val :: Int
  , fun :: Int -> Int
  }

apply :: Foo -> Int
apply foo = foo.fun foo.val

The RDS proposal says that "dot binds tighter than function application", so I was expecting the above program to be accepted, with foo.fun foo.val being parsed as (foo.fun) (foo.val). However, GHC gives a type error suggesting that it has been parsed as ((foo.fun) foo).val.

In contrast, Prelude.succ foo.val does indeed parse as (Prelude.succ) (foo.val).

I also note the committee's RDS Conclusion. The following bullet point is copied here for convenience:

The form r.x (with no spaces on either side of the dot) is not treated as a naked record selector; instead it is treated as an atomic expression, very like a qualified name M.x. So f r.x means f (r.x)

Steps to reproduce

I built GHC HEAD (commit 7a728ca6) and applied it to the above program.

To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information