[Haskell-cafe] Calculating a value as side effect of converting list of strings into list of records.

Eugeny N Dzhurinsky bofh at redwerk.com
Mon May 24 10:12:15 EDT 2010


Hello, All!

I need some help to solve the following task:

=================================================================================================
import Data.Map as M 
import Data.List as L

data Pair = Pair { name, value :: String }

type IxPair = (Int, String, String)

type IxPairParser = Pair -> Maybe IxPair

type RecordUpdateF r = String -> String -> r -> r

convertPairsToRecords :: RecordUpdateF r -> IxPairParser -> r -> [Pair] -> [r]
convertPairsToRecords updateRecF parsePairF initRec pairs = M.elems $ L.foldl' processWithPairs initMap pairs
    where
        initMap = M.empty
        processWithPairs resMap = maybe resMap (updateMapF resMap) . parsePairF
        updateMapF res (idx, key, value) | idx `M.member` res = M.adjust (updateRecF key value) idx res
                                         | otherwise = M.insert idx (updateRecF key value initRec) res
=================================================================================================

In short, input looks like name=value pairs:
pair_1_username=user
pair_1_password=pass
pair_1_fullname=vasya poopking

The parser IxPairParser takes the pair of name=value, and extracts ordering
number of the current pair, making it a triple like below

(1, username, user)

then convertPairsToRecords takes the triple and performs lookup in the Map
for a record with given ID. Then it updates the record and places it back into
the map. If no record is found - then new one is created, updated and inserted
into the Map.

Now, I've got the case when input contains pairs like below

pair_1_lastlogin=2010-05-24 12:23
...
pair_2_lastlogin=2009-12-20 10:30
...
pair_2_lastlogin=2010-04-06 18:20

At this point I need to update the record and keep the latest date somewhere,
so it will be possible to extract the latest login date among all such pairs.

I can think about post-processing list [r], extract lastlogin field and simply
use fold to get the oldest one. But I'd like to calculate this information
during parsing of the input. And I am not allowed to change the interface of
convertPairsToRecords.

Can somebody please suggest how to solve the task? Probably with Writer monad,
or may be State?

Thank you in advance!

-- 
Eugene Dzhurinsky
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 196 bytes
Desc: not available
Url : http://www.haskell.org/pipermail/haskell-cafe/attachments/20100524/b476ae00/attachment.bin


More information about the Haskell-Cafe mailing list