[Haskell-beginners] Simple data summarization
Thomas Davie
tom.davie at gmail.com
Tue Mar 10 11:49:15 EDT 2009
On 10 Mar 2009, at 16:26, Roland Zumkeller wrote:
> Hi Andy,
>
> Here is a function that parses a comma-separated list of strings:
>
>> uncommas :: String -> [String]
>> uncommas s = case break (==',') s of
>> (w,[]) -> [w]
>> (w,_:s') -> w : uncommas s'
>
> We can then sum over the 4th column like this:
>
>> main = putStrLn . show . sum . map (read . (!!4) . uncommas)
>> . tail . lines =<< getContents
>
> This program is best read backwards: "getContents" gives stdin as a
> string and "lines" breaks it into lines. The (!!) function yields the
> nth element of a list. "read" and "show" convert between strings and
> integers.
An alternative solution, though similar is to implement a data type
for each record, and implement read for it:
data Gender = Male | Female
data Ethnicity = European | Maori | ..........
data Record = R {name :: String, gender :: Gender, age :: Int,
ethnicity :: Ethnicity, books :: Int}
instance Read Gender where
readsPrec _ s = case toLower $ read s of {'m' -> [(Male,"")]; 'f' -
> [(Female,"")]; _ -> []}
instance Read Ethnicity where
...
instance Read Record where
readsPrec _ = buildRec . uncommas
where
buildRec [n,g,a,e,b] =
fromMaybe []
do (n',_) <- listToMaybe $ reads n
(g',_) <- listToMaybe $ reads g
(a',_) <- listToMaybe $ reads a
(e',_) <- listToMaybe $ reads e
(b',_) <- listToMaybe $ reads b
return [(R n' g' a' e' b', "")]
Now you can get at just the names for example by mapping the getter
over the list:
main = putStrLn . ("Names: " ++) . concat . intersperse " " . map
(name . read) . lines =<< getContents
Bob
More information about the Beginners
mailing list