-5 haskell
当输入是数字时,我的搜索功能正常工作,但当输入不是时,我的搜索功能会崩溃.我可以添加什么来防止这种情况发生?
searchAge = do
putStrLn "\n Please type the age of the person you're looking for: \n"
age <- getLine
input <- readFile $ "databas.txt"
putStrLn "\n Here are all the people that matches your search: \n"
let people = parse input
output = map personToString (filter (\p -> personAge p == read age) people)
in putStrLn (unlines output)
putStrLn "Let's get back to the search menu again!"
searchDatabase
Run Code Online (Sandbox Code Playgroud)
Zet*_*eta 16
听,哦,年轻的,
因为这是一首令人发狂的歌.
看一看,你会发现你
read :: String -> Int错了.
它的类型错了,结果不明;
如果在字符串上使用过"frown".
但这是
你正在寻找的最后提示readMaybe :: String -> Maybe Int.
问题read是它的类型签名没有失败的概念:
read :: Read a => String -> a
Run Code Online (Sandbox Code Playgroud)
如果我们设置会发生什么a来Int,并尝试使用它的字符串"frown"?这将导致异常:
ghci> read "frown" :: Int
*** Exception: Prelude.read: no parse
Run Code Online (Sandbox Code Playgroud)
毕竟,它应该回归什么?来自域的任何内容Int都是有效值.
输入readMaybe :: Read a => String -> Maybe a.现在,类型签名中包含潜在错误,并且不再导致异常:
ghci> import Text.Read
ghci> readMaybe "frown" :: Maybe Int
Nothing
ghci> readMaybe "15" :: Maybe Int
Just 15
Run Code Online (Sandbox Code Playgroud)
我们可以将这个包装在一个新的函数中,该函数getNumber会反复询问,Int直到用户实际提供一个:
getNumber :: IO Int
getNumber = do
line <- getLine
case (readMaybe line :: Maybe Int) of
Just x -> return x
Nothing -> putStrLn "Please enter a number!" >> getNumber
Run Code Online (Sandbox Code Playgroud)
然后你可以使用它来Int代替String你的age:
searchAge = do
...
age <- getNumber
input <- readFile "databas.txt"
putStrLn "\n Here are all the people that matches your search: \n"
let people = parse input
output = map personToString (filter (\p -> personAge p == age) people)
in putStrLn (unlines output)
Run Code Online (Sandbox Code Playgroud)