读取字符串输入

时间:2012-11-24 23:37:33

标签: haskell

我正在尝试编写Read类的实例,以将输入读取为字符串,如下所示:

"1 3 -    
 - 2 3      
 - - 5" 

将其转换为[[Maybe Int]]

“ - ”将被翻译为Nothing “3”将为Just 3

"('a',3) - ('b',7)
 ('c',5) ('e',0) -  
 ('d',9) - ('h',8)"

将其转换为[[Maybe (Char,Int)]]

“ - ”将被翻译成Nothing “('a',3)”将为Just ('a',3)

我尝试通过处理List of Char来编写它们,但它需要做很多工作。你有什么建议吗?对不起,我对Haskell很新,所以我问你这个问题。 :(

1 个答案:

答案 0 :(得分:4)

如果您删除了-个条目,则可以非常快速地执行此操作

Prelude> (map (map read) . map words. lines $ "('a',3) ('b',4)\n('c',5)")::[[(Char,Int)]]
[[('a',3),('b',4)],[('c',5)]]

或者将其定义为函数

genericReadLines :: Read a => String -> [[a]]
genericReadLines = map (map read) . map words. lines

您可以这样使用:

*Main> (genericReadLines "('a',3) ('b',4)\n('c',5)")::[[(Char,Int)]]
[[('a',3),('b',4)],[('c',5)]]

但你可能会觉得更容易

readCharInts :: String -> [[(Char,Int)]]
readCharInts = genericReadLines

readInts :: String -> [[Int]]
readInts = genericReadLines

所以你可以输入

*Main> readInts "1 2 3\n4 5 6\n7 8 9"
[[1,2,3],[4,5,6],[7,8,9]]
*Main> readCharInts "('a',3) ('b',4)\n('c',5)"
[[('a',3),('b',4)],[('c',5)]]

但保持-呢?您必须使用Maybe数据类型来表示列表中的某些点没有值;我们可以使用-作为Nothinga的简写作为Just a的简写。

read' :: Read a => String -> Maybe a
read' "-" = Nothing
read' xs = Just (read xs)

如果您的数据可能是'-',我应该警告您,该代码很脆弱,但可能不是。

genericMaybeReadLines :: Read a => String -> [[Maybe a]]
genericMaybeReadLines = map (map read') . map words. lines

然后我们可以

readMaybeCharInts :: String -> [[Maybe (Char,Int)]]
readMaybeCharInts = genericMaybeReadLines

readMaybeInts :: String -> [[Maybe Int]]
readMaybeInts = genericMaybeReadLines

现在我们可以做到

*Main> readMaybeCharInts "('a',3) ('b',4)\n- ('c',5)"
[[Just ('a',3),Just ('b',4)],[Nothing,Just ('c',5)]]
*Main> readMaybeInts "2 3 -\n4 - 2"
[[Just 2,Just 3,Nothing],[Just 4,Nothing,Just 2]]