2012-06-13 15 views
10

ファイル全体を文字列に読み込み、関数linesを使用して文字列の行を取得したいとします。私はこれらのコード行でそれをやろうとしている:Haskellがファイルの行を読み取る

main = do 
    args <- getArgs 
    content <- readFile (args !! 0) 
    linesOfFiles <- lines content 

しかし、私はそれが失敗した広告コンパイルして、次のエラーを取得しています:私はreadFileの結果を結合することによって考え

Couldn't match expected type `IO t0' with actual type `[String]' 
In the return type of a call of `lines' 
In a stmt of a 'do' block: linesOfFiles <- lines content 

を内容はStringデータ型になります。それはなぜですか?

答えて

30

readFileの結果をコンテンツにバインドすると、それはString DataTypeになると思ったのですが、それはなぜですか?

確かに、それはコンパイラが不満を述べるものではありません。これは実際にはStringです。コードを見てみましょう:

main = do 
    args <- getArgs 
    content <- readFile (args !! 0) 

contentは、必要に応じて、平野Stringです。そしてlines content[String]です。しかし、あなたは次の行にIO()行うブロックで

linesOfFiles <- lines content 

を結合モナドを使用しています。したがって、<-の右側にタイプIO somethingの式が必要ですが、[String]が見つかります。

計算lines contentはどんなIOを伴わないので、あなたが代わりにモナド結合の結合letとその結果をバインドする必要があり、

let linesOfFiles = lines content 

は、あなたがそこに必要なラインです。

+0

さらに、これを完全性のためにgetArgsおよびreadFileの型と比較してください。 –

+0

このソリューションはどのように機能しますか? 'lines'の型が' String - > [String] 'で、' content'の型が 'IO String'であるため' content'を 'lines'に渡すことはできません – imkendal

+1

@kjhいいえ、' content'はa 'String'。 'readFile(args !! 0)'の型は 'IO String'で、' content'をその 'IO'アクションの" result "に束縛します。構造体 'do {a < - action;もの; } ''アクション '= \ a - > stuff'に' 'desugars''、' 'アクション' 'が' 'IO''型の場合、' a'は 't'型です。 –