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