Haskell IO String -> Список - PullRequest
2 голосов
/ 12 мая 2011

Эй, ребята, мне нужна помощь, как я могу суммировать список из файла, используя встроенную функцию sum?

Пример: text.txt содержит [1,2,3,4]

и я хочу получить этот список из файла и сложить эти числа со встроенной суммой. Возможно ли это?

Спасибо!

Ответы [ 3 ]

3 голосов
/ 12 мая 2011

Итак, вы не сможете получить значение :: [Int], потому что это будет небезопасно.Но мы можем получить вам IO [Int], а затем передать через >>= в print:

main = (sum . read) `fmap` readFile "myFile" >>= print

Если вы используете Control.Applicative, вы можете сделать его еще красивее:

main = sum . read <$> readFile "myFile" >>= print

Вуаля!Как видите, этот способ гораздо более лаконичен, чем использование примечания do.do - примечание отлично подходит для избавления от вложенных лямбд, но во многих случаях это действительно не нужно.

Edit: @ augustss предлагаетследующая превосходная альтернатива:

main = print . sum . read =<< readFile "myFile"

Это потрясающе, так как оно проще и не зависит от Control.Applicative;что еще более важно, его не нужно читать, чтобы читать «наизнанку», как указывает @ hammar .

2 голосов
/ 12 мая 2011

Конечно.

main = do
    contents <- readFile "text.txt"
    print . sum . read $ contents

Здесь используются некоторые стандартные функции из Prelude:

  • readFile :: FilePath -> IO String читает файл в строку.

  • read :: Read a => String -> a преобразуется из String в любой тип в классе типов Read.Возможно, вам придется добавить аннотацию типа, если компилятор не может определить, какой тип вам нужен.В этом случае компилятор может понять это, так как мы использовали sum для результата, поэтому он делает вывод, что a должно быть [Integer].(На самом деле вывод Num a => [a], но по умолчанию [Integer] из-за типа по умолчанию).

    read ожидает тот же формат, сгенерированный show для того же типа.

Обратите внимание, что мне пришлось использовать do-нотацию, чтобы извлечь String из IO String, чтобы применить к нему read.

1 голос
/ 12 мая 2011

Если список всегда в таком формате, вы хотите использовать функцию read.Эта функция десериализует данные, т.е. превращает строку в программный тип данных.Например,

Prelude> read "[1, 2, 3, 4]" :: [Int]
[1,2,3,4]

Теперь вы можете комбинировать это с файловым вводом-выводом, но вам нужно прочитать о Monads, если вы не знакомы.Некоторые хорошие ресурсы - [http://www.haskell.org/haskellwiki/Monad] и Википедия.По сути, каждая монада будет представлять собой шаг в последовательном выполнении - что необходимо, поскольку IO изменяет среду, поэтому необходимо определить порядок ее выполнения.

Код, который я придумал для чтения и затем суммирования:

main = do
    fc <- readFile "file1"
    parsed <- return (read fc :: [Int])
    putStrLn (printf "sum: %d" (sum parsed))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...