чтение файлов на Haskell

Я только недавно начал изучать 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 Я прочитал его полностью

27
задан DustBunny 23 October 2011 в 17:11
поделиться

2 ответа

Неплохое начало! Единственное, что нужно помнить, это то, что приложение чистой функции должно использовать 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
55
ответ дан 28 November 2019 в 04:41
поделиться

Для всех вас, нефункциональных программистов, есть угощение

unsafePerformIO . readFile $ "file.txt"

Считывает файл в строку

Нет строки ввода-вывода, просто обычная полностью загруженная строка, готовая к использованию. , Возможно, это не правильный путь, но он работает, и нет необходимости изменять существующие функции в соответствии с IO String

p.s. Не забудьте импортировать

import System.IO.Unsafe 
0
ответ дан 28 November 2019 в 04:41
поделиться
Другие вопросы по тегам:

Похожие вопросы: