If you got rid of the -
entries, you could do this very quickly as
Prelude> (map (map read) . map words. lines $ "('a',3) ('b',4)
('c',5)")::[[(Char,Int)]]
[[('a',3),('b',4)],[('c',5)]]
Or define it as a function
genericReadLines :: Read a => String -> [[a]]
genericReadLines = map (map read) . map words. lines
Which you can use thus:
*Main> (genericReadLines "('a',3) ('b',4)
('c',5)")::[[(Char,Int)]]
[[('a',3),('b',4)],[('c',5)]]
but you may find it easier to do
readCharInts :: String -> [[(Char,Int)]]
readCharInts = genericReadLines
readInts :: String -> [[Int]]
readInts = genericReadLines
So you can just type
*Main> readInts "1 2 3
4 5 6
7 8 9"
[[1,2,3],[4,5,6],[7,8,9]]
*Main> readCharInts "('a',3) ('b',4)
('c',5)"
[[('a',3),('b',4)],[('c',5)]]
But what about keeping the -
? You'll have to use a Maybe data type, to represent not having a value for certain points in your list; we can use -
as shorthand for Nothing
and a
as shorthand for Just a
.
read' :: Read a => String -> Maybe a
read' "-" = Nothing
read' xs = Just (read xs)
I should warn you that that code is fragile if your data could possibly be '-'
, but perhaps it can't.
genericMaybeReadLines :: Read a => String -> [[Maybe a]]
genericMaybeReadLines = map (map read') . map words. lines
Then we can have
readMaybeCharInts :: String -> [[Maybe (Char,Int)]]
readMaybeCharInts = genericMaybeReadLines
readMaybeInts :: String -> [[Maybe Int]]
readMaybeInts = genericMaybeReadLines
So now we can do
*Main> readMaybeCharInts "('a',3) ('b',4)
- ('c',5)"
[[Just ('a',3),Just ('b',4)],[Nothing,Just ('c',5)]]
*Main> readMaybeInts "2 3 -
4 - 2"
[[Just 2,Just 3,Nothing],[Just 4,Nothing,Just 2]]