2012-04-01 51 views
1

我想解析用户输入的字符串像“A12”,到一个Haskell元组,像('A',12)。解析用户输入Haskell读取

这是我曾尝试:

import Data.Maybe 

type Pos = (Char, Int) 

parse :: String -> Maybe Pos 
parse u = do 
    (c, rest) <- (listToMaybe.reads) u 
    (r, _) <- (listToMaybe.reads) rest 
    return $ (c, r) 

但这总是返回Nothing。为什么会发生这种情况,解析这个字符串的正确方法是什么?由于这很简单,我想避免使用Parsec或类似的高级解析库。

EDIT(澄清): 样本输入和输出:

"A12"给出Just ('A', 12)

"J5"给出Just ('J', 5)

"A"给出Nothing

"2324"给出Nothing

回答

4

read通常的show相反,他们都普遍采用Haskell语法表示给定值。这意味着由于字符的Haskell语法使用单引号,因此字符上的show将在其周围添加单引号,并且read将期望单引号出现在那里。

换句话说,你的函数需要类似语法'A' 42,而事实上,如果你尝试的作品:

> parse "'A' 42" 
Just ('A',42) 

为了您的格式,我反而使用模式匹配的第一个字符,然后reads为休息,例如这样的事情:

parse :: String -> Maybe Pos 
parse [] = Nothing 
parse (c:rest) = do 
    (r, _) <- listToMaybe $ reads rest 
    return (c, r) 
0

您是否必须使用do表示法?如果不是,以下功能适合您的需求。这不太好,但它完成了工作。

parse :: String -> Maybe Pos 
parse (x:xs) = Just (x,read xs::Int) 

我不知道你认为是“失败的”,因而值得的Nothing

+0

请参阅问题中的编辑,说明我的意思。 另外,“read xs :: Int”在创建异常的上面的回答中可能会失败。在这些情况下,我只想得到一个Nothing。 – donatello 2012-04-01 10:42:03