2016-05-31 8 views
1

ファイルから行を読み込み、intに解析して印刷するプログラムを作成するにはどうすればいいですか? "read"のようなものはありますか?IO StringHaskell - ファイルから1つのintを読み取り、それを印刷する

私はこれまでのところ、これを持っているが、私はIO種類の周りに得ることができませんでした:あなたは、文字列にファイルを変換するにはreadFile機能を使用することができます

readFromFile = do 
    inputFile <- openFile "catalogue.txt" ReadMode 

    isbn <- read(hGetLine inputFile) 


    hClose inputFile 

答えて

0

まず、その読書のものを観察し、その後すぐに、それは神秘的なエラーが発生することができ、印刷:

GHCi, version 8.0.0.20160421: http://www.haskell.org/ghc/ :? for help 
Prelude λ read "123" 
*** Exception: Prelude.read: no parse 

理由は、あなたが読みたいタイプを指定していないということです。

Prelude λ read "123" :: Integer 
123 

が、少しヘルパー関数を導入することが時には簡単です:あなたは、型注釈を使用してこれに対抗することができます主な問題に今

Prelude λ let readInteger = read :: String -> Integer 
Prelude λ readInteger "123" 
123 

を。 read(hGetLine inputFile)hGetLine inputFileが返され、IO StringreadStringを必要とするために機能しません。これは、2つの段階で解決することができます。

line <- hGetLine inputFile 
let isbn = readInteger line 

注2つの異なる構築<-let .. =、彼らは別のことを行います。あなたは何を正確に把握できますか?

別の答えに示すように、あなたはそれほど冗長な方法でそれを行うことができます。

ISBN < - あなたはreadような単純なことを行う場合に最適ですFMAP readInteger(hGetLineで、inputFile)

。しかし、中間結果に明示的に名前を付けることがしばしば望ましい。このような場合には、<-およびlet .. =構成を使用できます。

+0

それはまだ私のために少し曇っています。 readIntegerはString - > Intですので、 "let .. ="は何とかIO String - > IO Integerに変更されます。あれは正しいですか? –

+0

正確ではありません。 'hGetLine inputFile'は' IO String'ですが、 'line < - hGetLine inputFile'と言うと、' line'は単に 'String'です。 'let .. ='はIOを追加しません。あなたは 'do'ブロックの最後の行で、例えば' print isbn'を使ってIOに戻る必要があります(これは 'IO()'を返します)。 –

+0

'line < - hGetLine inputFile'、 '< - 'は 'IO String'を 'String'に変換しますか? –

1

main = do 
    contents <- readFile "theFile" 
    let value = read $ head $ lines contents::Int 
    print value 

あなたはより良いエラー検出を追加する必要があり、または最初の行がない場合、このプログラムは失敗する、または値が不正な形式であれば、これは基本的な流れである....

+0

値はどのようにIO Intの代わりにInt型ですか? –

+1

ハスケルの表記法では、 '< - 'の左の値は実際にモナド(この場合はIO)が削除されたアイテムの型を持っています。したがって 'readFile'行は' IO String'型を持っていますが、次の行では 'String'型だけです。 – jamshidh

+0

"value < - value"のようにIOも削除されますか? –

2

ますタイプIO Stringであり、あなたがIntとして読むために「内部」を取得するためにfmapを使用する必要がありますhGetLine inputFileとして

isbn <- fmap read (hGetLine inputFile) :: IO Int 

に読み出し行を変更し、明示的に型を指定することができます。

+0

あまり速くない!まだghc 6にいる人がいます! –

+0

fmapは実際に何をしていますか? –

+0

@EricMarchettiSantos IOの下で 'IO - > IO b'として動作するようにプレーン関数' a - > b'を変えます(他のファンクタでも動作します)。 – chi

関連する問題