haskell检查用户输入错误

时间:2010-05-28 18:28:48

标签: haskell

我在haskell中编写应用程序,我想知道这是检查用户输入是否正常的最佳方法,例如,当我要求int时它是int,还是在请求格式良好的日期时它是否为日期?

感谢您的帮助

4 个答案:

答案 0 :(得分:7)

使用maybeRead。该功能是候选人 包含在Haskell库中,但它还没有成功 然而。所以包括它的代码。这是一个完整的解决方案:

import Data.Time
import Data.Maybe (listToMaybe)
import System.IO (hSetBuffering, BufferMode(NoBuffering), stdout)

main = do hSetBuffering stdout NoBuffering putStr "Enter an Int: " maybeInt <- fmap maybeRead getLine :: IO (Maybe Int) maybe (putStrLn "That's not an Int!") (putStrLn . ("The Int is " ++) . show) maybeInt putStr "Enter a date: " maybeDate <- fmap maybeRead getLine :: IO (Maybe Day) maybe (putStrLn "That's not a date!") (putStrLn . ("The date is " ++) . show) maybeDate

maybeRead :: Read a => String -> Maybe a maybeRead = fmap fst . listToMaybe . filter (null . snd) . reads

答案 1 :(得分:3)

对于Integer,最简单的方法是使用“读取”。这有类型:

type ReadS a = String -> [(a, String)]

reads :: (Read a) => ReadS a

这个想法是,对于作为Read类的一个实例的任何类型,你将字符串传递给它,并尝试将其解析为该类型。例如,Integer是Read的实例,因此您可以将类型视为

reads :: String -> [(Integer, String)]

如果成功,则结果将包含一个带有数字和字符串其余部分的条目。所以例如

reads "45xyz" = [(45, "xyz")]

所以在你的情况下只需要在[(v,“”)]上进行模式匹配来获取值,然后让acatch-all模式匹配抱怨它没有得到整数。

做日期更复杂。定义您的格式,然后将其分解为您可以使用“读取”识别的位。

答案 2 :(得分:0)

我喜欢在Parsec的命令行选项时这样做。如果命令行是字符串列表而不是字符串,我该怎么做?首先,您需要创建一些简单的原语来解析String的列表(而不是Char的列表):

http://github.com/solidsnack/system-uuid/blob/master/Options.hs

然后你可以编写那些来解析你的选项,就像我在这个文件的底部所做的那样:

http://github.com/solidsnack/system-uuid/blob/master/Main.hs

这实际上是最强大的方法,它利用了任何Haskell程序员在解析器组合器中所做的大量投资(就像任何Perl程序员在regexen中所做的那样沉重)。

答案 3 :(得分:0)

我会允许跟踪这样的空格:

import Data.Maybe
import Data.Char

maybeRead :: Read a => String -> Maybe a
maybeRead = fmap fst . listToMaybe . filter (null . dropWhile isSpace . snd) . reads