4 に答える
インデントが壊れています。これらはより良いです:
printFile :: Handle -> IO ()
printFile handle = do
end <- hIsEOF handle
if end
then return ()
else do line <- hGetLine handle
putStrLn line
printFile handle
printFile :: Handle -> IO ()
printFile handle = do
end <- hIsEOF handle
if end
then return ()
else do
line <- hGetLine handle
putStrLn line
printFile handle
if
よりもさらにインデントすることによりend <- hIsEof handle
、実際には行の継続であり、の後続のアクションではありませんでしたdo
。putStrLn line
同様に、インデントが少ないという事実はline <- hGetLine handle
、do
(の内側のelse
)がそこで終了したことを意味します。
いくつかの問題があります。まず、if
インデントが大きすぎます-はのend <- ...
最後の行であると見なされますdo
。インデント解除...
次号が出ます。同じエラーメッセージ、18行目のみ。今回は、19行目と20行目が十分にインデントされていません(の一部として解析されていませんdo
)。インデント(すべてが整列しているので、とにかく見栄えが良くなります)...次のエラーメッセージ。幸いなことに、今回はインデントエラーではなく、修正は簡単です。
test.hs:9:22:
Couldn't match expected type `([a] -> a) -> [String] -> FilePath'
against inferred type `IOMode'
In the second argument of `($)', namely `ReadMode head args'
In a stmt of a 'do' expression:
inh <- openFile $ ReadMode head args
In the expression:
do { args <- getArgs;
inh <- openFile $ ReadMode head args;
printFile inh;
hClose inh }
修正はinh <- openFile (head args) ReadMode
です。バージョンが正しくない理由/方法、またはエラーの意味についてより詳細な説明が必要な場合は、お知らせください。編集します。
あなたはこれを書いた:
main :: IO()
main = do
args <- getArgs
inh <- openFile $ ReadMode head args
printFile inh
hClose inh
しかし、それはおそらくこのように良いです:
main :: IO()
main = do
args <- getArgs
withFile (head args) ReadMode printFile
{ ; }
この空白の愚かさを心配する必要がないように、いつでも明示的なブラケットを使用できます。
printFile :: Handle -> IO ()
printFile handle = do {
end <- hIsEOF handle ;
if end
then return ()
else do { line <- hGetLine handle ;
putStrLn line ;
printFile handle }}
(のように、エラーを引き起こさないように)完全に問題がなかったでしょう。
I / Oはdo
、Haskellの特別な""言語で処理されます。それは受け入れられるべきです。それが実際にモナドを介して実装されていることは、実装の詳細です。
明確にするために:中かっこが優れているとは思いません。中かっこは、適切で一貫したインデントと一緒に使用する必要があると思います。中かっこは、コードの構造に関する優れた視覚的な手がかりを与えてくれます。もちろん、ワイルドインデントはほとんどの場合無意味な気晴らしになります。しかしまた、中かっこはコードが機能することを保証し、空白の事故の無意味な心配から私たちを解放します。彼らはこのもろさを取り除きます。