1. ホーム
  2. file

[解決済み] Haskellファイル読み込み

2022-02-10 02:42:33

質問

最近Haskellを学び始めたのですが、ファイル読み込みがどのように行われるのかがわからず、困っています。

例えば、私は数字が書かれた行を含むテキストファイル "test.txt" を持っています。

32 4
2 30
300 5

各行を読んでから、各単語を評価し、追加したい。

したがって、次のようなことをやろうとしているのです。

import System.IO
import Control.Monad

main = do
        let list = []
        handle <- openFile "test.txt" ReadMode
        contents <- hGetContents handle
        singlewords <- (words contents)
        list <- f singlewords
        print list
        hClose handle

f :: [String] -> [Int]
f = map read

完全に間違っているのは分かっているのですが、構文の正しい使い方が全く分かりません。

また、例題やコードの説明がある良いチュートリアルのリンクもお願いします。 これ を完全に読みました。

解決方法は?

まずまずの滑り出しです。ただひとつ覚えておいてほしいのは、純粋な関数アプリケーションでは let の代わりに、バインディングの <- .

import System.IO  
import Control.Monad

main = do  
        let list = []
        handle <- openFile "test.txt" ReadMode
        contents <- hGetContents handle
        let singlewords = words contents
            list = f singlewords
        print list
        hClose handle   

f :: [String] -> [Int]
f = map read

これが、コンパイルして実行するために必要な最小限の変更点です。スタイル的には、いくつかのコメントがあります。

  1. バインディング list は少し怪しげに見えます。これは値 list -- 代わりに古い定義をシャドウイングしています。
  2. 純粋な関数をもっとたくさんインライン化しよう
  3. 可能な場合は readFile は、手動でファイルを開いたり、読んだり、閉じたりするよりも望ましいです。

この変更を実装すると、次のようになります。

main = do  
        contents <- readFile "test.txt"
        print . map readInt . words $ contents
-- alternately, main = print . map readInt . words =<< readFile "test.txt"

readInt :: String -> Int
readInt = read