Фильтрация по длине строк в файле дает неожиданный результат - PullRequest
0 голосов
/ 11 декабря 2018

Я пробираюсь через Learn You a Haskell к большому благу.В настоящее время я нахожусь в разделе файлов и потоков главы 9. По какой-то причине, когда я пытаюсь передать код в одну из примеров программ на Haskell, я не получаю тот же вывод, что и книга.Использование команд ConEmu для Linux в Windows.Например, у меня есть программа, которая печатает только строки длиной менее 10 символов с кодом ниже (short_lines.hs):

main = interact $ unlines . filter ((<10) . length) . lines

Я собираюсь передать этот файл (short_long.txt):

i'm short
so am i
i am a loooooooooong line!!!
yeah i'm long so what hahahaha!!!!!!
short line
loooooooooooooooooooooooooooong
short

Вот команда:

cat short_long.txt | runhaskell short_lines.hs

Вот мой вывод:

so am i
short

В книге сказано, что вывод следующий:

i'm short  
so am i  
short 

Я считаю, что это связано с обработкой символа новой строки, но я не могу понять это, поскольку строки должны были удалить символы новой строки перед фильтрацией.Он работает с ручным вводом, но не с трубопроводом.Почему я получаю другой вывод?Я делаю что-то неправильно?Я попытался удалить завершающие символы новой строки в редакторе Atom, но это ничего не изменило.Будем весьма благодарны за любую помощь, почему я не получаю ожидаемый результат и что я могу сделать, чтобы получить ожидаемый результат.Спасибо!

Ответы [ 2 ]

0 голосов
/ 11 декабря 2018

Я обнаружил, что могу изменить стиль окончания строки с Windows-CRLF на Unix-LF в редакторе Atom.В настоящее время он расположен снизу и просто говорит CRLF или LF.Вы можете нажать на нее, чтобы выбрать другой стиль линии.Для этой книги я буду использовать это для простоты.Тем не менее, я считаю, что ответ Амаллоя - это лучший долгосрочный универсальный подход к ИО.

0 голосов
/ 11 декабря 2018

Режим новой строки по умолчанию для стандартного ввода: nativeNewline, который выбирает свое поведение в зависимости от того, каким он считает вашу ОС.Я подозреваю, что он (ошибочно) решил, что вы работаете в системе Unix, и поэтому не должен выполнять преобразование CRLF;таким образом, при задании файла в стиле Windows каждая строка имеет завершающий символ '\r'.Попробуйте использовать

import System.IO

main = do
  hSetNewlineMode stdin universalNewlineMode
  interact $ unlines . filter ((<10) . length) . lines

для принудительного преобразования CRLF и посмотрите, даст ли это ожидаемые результаты.

Я могу воспроизвести вашу проблему в моей системе Unix, преобразовав текстовый файл в режим DOS, прежде чем датьэто к вашей программе.Сделав это, мое предлагаемое исправление получает желаемое поведение.

...