2012-04-01 82 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