LINUX.ORG.RU

Haskell и построчное считывание из файла.

 


0

2

Итак, надо написать программу, которая считает файл с текстом, а потом поменяет слова местами и выведет на экран.

написал такое:

import System.Environment

main :: IO ()
main = do
    (path:_) <- getArgs
    contents <- readFile path
    putStrLn $ reverseWords $ words contents


reverseWords :: [[Char]] -> [Char]
reverseWords [] = []
reverseWords (x:[]) = x
reverseWords (x:xs) = reverseWords xs ++ " " ++ x

но оно выводит файл в одну строку. если же убрать функции и написать

putStrLn contents
то выводит содержимое как надо. Вывод, всё дело в words. Не могу разобраться.



Последнее исправление: dodevich (всего исправлений: 1)

дело в том, что:

words "i\nam\nretard" == ["i", "am", "retard"]
а ты отдаёшь строки с «\n» под words.

f1u77y ★★★★
()
Ответ на: комментарий от anonymous

Да нет. Проблема в том, что ТС не понимает, что монада это моноид в категории эндофункторов. Если здесь завяжется срачик, то примерно к десятой странице подтянется квазимото и всё объяснит.

Virtuos86 ★★★★★
()
Ответ на: комментарий от KblCb

У тебя опечатка. Ты хоть предупреждай, что код не проверял на работоспособность, зачем палиться так глупо. И выглядит как однострочник, зачем это всё?

Virtuos86 ★★★★★
()
Ответ на: комментарий от Virtuos86

Монады тут не нужны, достаточно понимания функторов, хватит уже лезть в хацкель треды с таким экспертным мнением.

qnikst ★★★★★
()
Ответ на: комментарий от qnikst

Хоть я тебя и держу в игноре, ради интереса спрошу: почему ради довольно простой задачи обязательно нужны функторы в этом вашем «хацкеле»?

Virtuos86 ★★★★★
()
Ответ на: комментарий от qnikst

Да читаем. Но когда до дела - так опыта не хватает. А вот Вы написали бы поизящнее, с функторами. А то читаешь читаешь, да увидеть нормальное применение сложно (на простом примере).

dodevich
() автор топика
Последнее исправление: dodevich (всего исправлений: 1)
Ответ на: комментарий от Virtuos86

Рука сломана. Писать развёрнутый ответ неудобно.

\txt -> unlines (reverse (map (\str -> unwords (reverse (words str))) (lines txt)))

Так больше нравится? Вообще тебя не поймёшь: монады и функторы не нравятся, композиция функций стандартной библиотеки не нравится.

KblCb ★★★★★
()
Ответ на: комментарий от KblCb

Мне много, что не нравится, но хаскел и его сущности мне монопенисуальны, вопреки мнению некоторых. Мне лишь показалось, что топикстартеру может оказаться затруднительным разбор предложенного кода, коль скоро он начинающий «штангист».

Руке здоровья.

Virtuos86 ★★★★★
()
Последнее исправление: Virtuos86 (всего исправлений: 1)
Ответ на: комментарий от Virtuos86

Код разбирать несложно. 2-3 книги прочитано. Применение просто только началось с минимальных задач. Оказалось, без опыта всё печально. И забывается ну совсем, хотя над некоторыми главами (так как в математике - дуб) сидел долго, что-бы понять.

dodevich
() автор топика

Ты совершенно не понимаешь сути Haskell, он не предназначен для этого, он работает по-другому.

anonymous
()
Ответ на: комментарий от KblCb

Вот парочка вариантов на Io

File with("file") contents split("\n") map (split(" ") reverse join(" ")) join("\n") println

File with("file") open foreachLine(x,y, y split(" ") reverse join(" ") println) 

Насколько я понял, у тебя код не полностью, так что на Io круче.

Но эта задача уж слишком простая, а покажи-ка, какой будет код, если надо не просто реверснуть каждую строку, а, скажем, поменять местами каждые 2 слова в ней.

drMits
()
Ответ на: комментарий от dodevich

Так я че то не понял, где он там бьет попарно? Или он гонит?

drMits
()
Ответ на: комментарий от dodevich

Я, кстати, сразу так и понял задачу, написал

File with("file") contents split("\n") foreach(
 allMatchesOfRegex("\\S+\\s+\\S+") map(captures at(0) split reverse join(" ")) join(" ") println
)
Потом ораторы выше сбили меня с толку, я подумал, что н так понял:)

Не особо изящно получается, может потому что я Io знаю не особо, но всяко лучше чем на хашкеле:)

drMits
()
Ответ на: комментарий от dodevich

Да ладно тебе. Обычный шашлык такой. Вполне себе легко читаемый, причём.

    main :: IO ()
    main = do
      input <- getContents
      let reverseWords = unwords . reverse . words
          output = unlines . map reverseWords . lines $ input
      putStr output
nezamudich ★★
()
Ответ на: комментарий от drMits
main :: IO ()
main = readFile "file.txt" >>= putStr . pipe
    where
        switch xs = case xs of
            w1 : w2 : ws -> w2 : w1 : switch ws
            _            -> xs

        pipe      = unlines . map (unwords . switch . words) . lines

Ты об этом?

KblCb ★★★★★
()
Ответ на: комментарий от drMits

Если коротко то это сопоставление с образцом. Если бы я хотел собрать в список два слова w1 и w2, а также список слов ws, я мог бы записать это как w1 : w2 : ws. Но в case-выражение я делаю примерно наоборот: я беру входной список и смотрю не соответствует ли он списку собранному из двух слов и произвольного списка слов. Если да, то создаются переменные w1, w2 и ws соответствующие описанным сущностям.

KblCb ★★★★★
()
Ответ на: комментарий от drMits

Я вот не пойму, откуда беруться вот эти w

w1 : w2 : ws

? это что, разновидность сахара чтоли?

В хаскеле : это конструктор списка (тип List). Конструкция w1 : w2 : ws описывает список, первый элемент которого будет помещен в переменную w1, второй — в w2, а оставшаяся часть (хвост списка) — в ws. В хаскеле вообще сплошной «сахар».

Virtuos86 ★★★★★
()
Ответ на: комментарий от drMits

Это тот самый паттерн матчинг, который ты «понял» и «разоблачил».

Kuzy ★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.