Я только недавно начал изучать 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
Я знаю, что это совершенно неправильно, но я совершенно не знаю, как правильно использовать синтаксис. Любая помощь будет очень признательна. А также ссылки на хорошие учебники, в которых есть примеры и объяснение кода, кроме этого: http://learnyouahaskell.com/input-and-output Я прочитал его полностью
Неплохое начало! Единственное, что нужно помнить, это то, что приложение чистой функции должно использовать 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
Это минимальное изменение, необходимое для компиляции и запуска. Стилистически у меня есть несколько комментариев:
list
дважды выглядит немного неясной. Обратите внимание, что это не изменяет значение list
- оно затеняет старое определение. 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
Для всех вас, нефункциональных программистов, есть угощение
unsafePerformIO . readFile $ "file.txt"
Считывает файл в строку
Нет строки ввода-вывода, просто обычная полностью загруженная строка, готовая к использованию. , Возможно, это не правильный путь, но он работает, и нет необходимости изменять существующие функции в соответствии с IO String
p.s. Не забудьте импортировать
import System.IO.Unsafe