を使用するord
と、型は一致しますord
が、数値ではなく ascii 値が得られるため、必要なものではありません: ord 5
is 53
、 not 5
. 48 を引いて数字を取得し、その数字をロールアップして 1 つの数字にすることもできますが、ライブラリ関数を使用する方が簡単です。最も簡単な選択は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
などに変換します.