如果您使用ord
,则类型匹配,但这不是您想要的,因为ord
给您的是 ascii 值,而不是数值:ord 5
is 53
, not 5
。您可以减去 48 来获得数字,然后将数字累加成一个数字,但使用库函数会更容易。最直接的选择是read
:
getInt :: IO Integer
getInt = do
y <- readFile "foo.txt"
return (read (takeWhile (/='\n') y))
与链接的答案一样,这里最好的解决方案是使用reads
.
reads
找到一个可能匹配的列表,作为对(match,remainingstring)
,这对你很有效,因为它会自动将换行符留在剩余的字符串中,
*Main> reads "31324542\n" :: [(Integer,String)]
[(31324542,"\n")]
让我们使用它:
findInt :: String -> Maybe Integer
findInt xs = case reads xs of -- have a look at reads xs
((anint,rest):anyothers) -> Just anint -- if there's an int at the front of the list, just return it
_ -> Nothing -- otherwise return nothing
Maybe
'一种方便的数据类型,可以让您在不崩溃程序或进行异常处理的情况下发生故障。
Just 5
意味着你得到了输出,它是5
. Nothing
表示有问题,没有输出。
addTen :: FilePath -> IO ()
addTen filename = do
y <- readFile filename
case findInt y of
Just i -> putStrLn ("Added 10, got "++show (i+10))
Nothing -> putStrLn ("Didn't find any integer at the beginning of " ++ filename)
这给了你:
*Main> addTen "foo.txt"
Added 10, got 1234567890
如果你只想要字符代表的整数,你可以放在import Data.Char
文件的顶部并做
ordzero = ord '0' -- handy constant, 48, to unshift the ascii code to a digit.
getInts :: FilePath -> IO [Int] -- ord gives the smaller Int, not Integer
getInts filename = do
y <- readFile filename
return [ord achar - ordzero | achar <- takeWhile isDigit y]
y
只要字符串的字符是数字,这就会获取字符串的字符,然后找到它们的ord
,减去ord '0'
(即 48)'4'
变成4
等。