Haskell 2010 Records as Syntactic Sugar

To support the record system of Haskell 2010/98 in HTE, it is enough to add the following rules to the desugaring phase:

  • Generating Functions

    For each datatype D,
    > data X = X1 | X2   Int | X3 { l1 :: String} | X4  { l2 :: Int, l1::String}

    1. Default data constructors:
      for each constructor Ci,  generate a function named newCi of type newCi :: D that constructs a new value of type D using Ci and undefined in each field.
      > newX1,newX2,newX3,newX4 :: X
      > newX1 = X1
      > newX2 = X2 undefined
      > newX3 = X3 undefined
      > newX4 = X4 undefined undefined
    2. Match functions:
      for each constructor Ci, generate a function named isCi of type isCi :: D -> Bool that checks if a value of type D is tagged with Ci.
      > isX1, isX2, isX3, isX4 :: X -> Bool
      > isX1 = \x -> case x of { X1         -> True ; _ -> False}
      > isX2 = \x -> case x of { X2 _     -> True ; _ -> False}
      > isX3 = \x -> case x of { X3 _     -> True ; _ -> False}
      > isX4 = \x -> case x of { X4 _ _ -> True ; _ -> False}
    3. Getter functions:
      for each label li :: Ti, generate a function named li of type li :: D -> Ti that extracts value of  the field labeled li.
      > l1 :: X -> String
      > l1 = \x -> case x of  { X3 x0 -> x0 ; X4 _ x0 -> x0 ; _ -> error “error!”}
      > l2 :: X -> Int
      > l2 = \x -> case x of {X4 x0 _ -> x0  ; _ -> error “error!”}
    4. Setter functions:
      for each label li :: Ti, generate a function named setli of type setli :: Ti -> D -> D that sets value of the field labeled li.
      > setl1 ::  String -> X  -> X
      > setl1 = \v -> \x -> case x of  { X3  _ -> X3  v ; X4  x0 _ -> X4  x0 v ; _ -> error “error!”}
      > setl2 :: Int -> X -> X
      > setl2 = \v -> \x -> case x of {X4 _ x0 -> X4  v  x0  ; _ -> error “error!”}
  • Desugar record update expression as a chain of setter function applications.
    > x { l1 = “test”, l2 = 1}   —>  ((setl2 1)   . (setl1 “test”)) x 
  • Desugar record constructor expression as the record update of  corresponding default data constructor.
    > X4 { l1 = “test”, l2 = 1} —> newX4 { l1 = “test”, l2 = 1}
  • Desugar  the empty record pattern Ci {} as a guard using the match function isCi.
    > f  (X2{})  = “test”  —> f x0 | isX2 x0 = “test”
  • Desugar the non-empty record pattern using patter guards, getter functions and empty record pattern.
    > f  (X4 {l2= 2, l1=x}) = “test”  —> f  (x0@(X4 {}))  | 2 <- l2 x0, x <- l1 x0 = “test”
  • Desugar data declaration with record syntax to the normal ADT syntax.
    data X = X1 | X2   Int | X3 { l1 :: String} | X4  { l2 :: Int, l1::String}
    >   —>
    > data X = X1 | X2   Int | X3            String    | X4             Int          String

For more details:
https://github.com/shayan-najd/Haskell-Desugar/blob/master/Language/Haskell/Exts/Desugar/Record.hs

About these ads

About Shayan

Researcher/Programmer at Chalmers University of Technology
This entry was posted in Articles. Bookmark the permalink.

2 Responses to Haskell 2010 Records as Syntactic Sugar

  1. Does this mean that HTE does not correctly support polymorphic record updates? I.e. what will happen in this case:

    > data X a = X { head :: a, tail :: [a], foo :: String }
    > bar :: X Int
    > bar = X 1 [2,3] “bar”
    > baz :: X Char
    > baz = bar { head = ‘x’, tail = ['y','z'] }

    Haskell (perhaps unfortunately) allows this, and to support updates like in baz, the updates of the ‘head’ and ‘tail’ fields need to happen at once.

  2. No, currently HTE does not support polymorphic record updates; I hadn’t noticed, thanks for pointing it out.

    The translation of the above would be:

    http://hpaste.org/74821

    and it does not compile “baz” .

    I refrained from implementing translations defined in Haskell report because desugaring in the usage site requires the full knowledge of the data declarations.
    For example:

    > bar { head = ‘x’, tail = ['y','z'] }

    is desugared [1] to

    > case bar of
    > X v1 v2 v3 -> X ‘x’ ['y','z'] v3
    > _ -> error “Update error”

    Such desugaring needs to know the signature of “X”.

    [1] http://www.haskell.org/onlinereport/haskell2010/haskellch3.html#x8-540003.15.3

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s