access to fields in nested records

Hal Daume III hdaume at ISI.EDU
Wed Nov 5 07:34:51 EST 2003


I think the following notation is all you need:

let x = DRoom 5 7 8 (DTable 1 2)
    y = x { square = 6, diningTable = diningTable x { tableSquare = 1 }}
in ...

 - Hal

On Wed, 5 Nov 2003, Serge D. Mechveliani wrote:

> Dear Haskellers,
> 
> My question is about a nice way to provide a getting/setting
> access to the nested record fields.
> 
> Example:
>   ---------------------------------------------------------------
>   data House = House {houseNo    :: Int, 
>                       diningRoom :: DiningRoom
>                      }                          deriving (Show)
>   data DiningRoom = DRoom {square       :: Int,
>                            height       :: Int,
>                            numOfWindows :: Int,
>                            diningTable  :: DTable                          
>                           }                       deriving (Show)
>   data DTable = DTable {tableSquare  :: Int,
>                         diningPlaces :: Int
>                        }                     deriving (Show)
>   -- example:
>   r1 = DRoom {square       = 50, 
>               height       = 300,
>               numOfWindows = 1,
>               diningTable  = dt
>              }                 
>              where  dt = DTable {tableSquare  = 16,
>                                  diningPlaces = 12
>                                 }
>   ---------------------------------------------------------------
>             
> Question 1:   how to change a field in a record?
> 
> I see the following way. For example,
> 
>   setSquare :: DiningRoom -> Int -> DiningRoom
>   setSquare    r             n   = 
>                              DRoom {square       = n, 
>                                     height       = height r,
>                                     numOfWindows = numOfWindows r,
>                                     diningTable  = diningTable r
>                                    }
> Example of usage:    setSquare r1 (square r2) 
>                      for 
>                      r1, r2 :: DiningRoom
> 
> Has indeed one to program the above functions, like  setSquare,  
> for all the records,  
> or there exist some Haskell annotations, or standard library 
> function for such purpose, which allow to skip extra remaining 
> fields in the data, like these three fields in  DiningRoom ?
> 
> 
> Question 2:   how to get/update a field in a nested record?
> 
> For example, 
>     dtableSquareFromRoom  :: DiningRoom -> Int
>     dtableSquareFromHouse :: House      -> Int
> 
>     dtableSquareFromRoom  = tableSquare . diningTable 
>     dtableSquareFromHouse = dtableSquareFromRoom . diningRoom
> 
>     setDTableSquareToHouse :: House -> Int -> House
>     setDTableSquareToHouse    h        n   = 
>       House {
>              houseNo    = houseNo h,
>              diningRoom = setDTableSquareToRoom (diningRoom h) n
>             }
>             where  setDTableSquareToRoom r n =  ...
> 
> Has indeed one to program such functions for each path to a
> field in the record nesting hierarchy?
> I see the main difficulty in a great number of functions to use 
> for the same field access from different structures. 
> 
> I try to improve this by adding classes with  get_  and  set_
> versions of operations for the record fields:
> 
>   class HouseLike a where  get_houseNo    :: a -> Int
>                            get_diningRoom :: a -> DiningRoom
> 
>                            set_houseNo    :: a -> Int -> a
>                            set_diningRoom :: a -> DiningRoom -> a
>   ...
> 
> Now, defining the instances, say, for   get_dtableSquare,
>                                         set_dtableSquare,
> 
> makes it a unique function pair to use for getting/setting of the
> corresponding field starting from
>                              House or DiningRoom or DiningTable.
> 
> Is this all a reasonable design for a Haskell user program?
> 
> Thank you in advance for the respond.
> 
> Please, add          mechvel at botik.ru  
> to the reply list.
> 
> ------------------
> Serge Mechhveliani
> mechvel at botik.ru  
> 
> 
> _______________________________________________
> Haskell mailing list
> Haskell at haskell.org
> http://www.haskell.org/mailman/listinfo/haskell
> 

-- 
 Hal Daume III                                   | hdaume at isi.edu
 "Arrest this man, he talks in maths."           | www.isi.edu/~hdaume



More information about the Haskell mailing list