使用Haskell中的读取解析用户输入

时间:2012-04-01 10:04:00

标签: parsing haskell

我试图将用户输入的字符串像“A12”解析为Haskell元组,如('A',12)。

以下是我的尝试:

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或类似的高级解析库。

编辑(澄清): 样本输入和输出:

"A12"提供Just ('A', 12)

"J5"提供Just ('J', 5)

"A"提供Nothing

"2324"提供Nothing

2 个答案:

答案 0 :(得分: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)

答案 1 :(得分:0)

您必须使用do表示法吗?如果没有,以下功能适合您的需求。它并不漂亮,但它完成了工作。

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

我不确定你认为“失败”是什么,因而值得Nothing