我在haskell中编写应用程序,我想知道这是检查用户输入是否正常的最佳方法,例如,当我要求int时它是int,还是在请求格式良好的日期时它是否为日期?
感谢您的帮助
答案 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