
2009/9/6 Günther Schmidt
I keep reading in and processing data in an accumulating way, ie. lets say I have a DB table (don't take this literally please, just an example), into in-memory records of type
data MyRecord = MyRecord { name :: String, birthDate :: LocalDate}
in a second step I read in Gender information so now I'd need an extended Record
data MyRecord = MyRecord { name :: String, birthDate :: LocalDate, gender :: Gender }
and so on for another 12 times.
In other words I need to extend the record.
I had been using tuples, ie:
(String, LocalDate) -> Gender -> (String, LocalDate, Gender)
but after 6 or so *extensions* things get a tad messy.
<snip>
So I wonder if there is a more simple way to do this, ie to *extend* the *type* signatures of extend records without such a lot of typing.
Do you actually need the intermediate data? More specifically, do you
need the data to be partial records?
One simple way to represent a partial record is a function which takes
the missing fields as arguments and returns the complete record, i.e.,
a constructor like MyRecord :: String -> LocalDate -> Gender ->
MyRecord.
So a partial result with the name filled in would have type LocalDate
-> Gender -> MyRecord.
More specifically, if the computations which produce the fields are
described using a monad or applicative functor, e.g., getName ::
Process String, you can just use <$> and <*> to glue them together.
MyRecord <$> getName <*> getDate <*> getGender
Or, if your process abstraction is a monad, you can do more complex operations.
do name <- getName
date <- getDate
gender <- getGender name date
return $ MyRecord name date gender
Instead of constructing intermediate records, all the data is kept in
variables until the record is complete.
--
Dave Menendez