Хламидомонада / Говнокод #12262 Ссылка на оригинал

0

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
  18. 18
  19. 19
  20. 20
  21. 21
  22. 22
  23. 23
  24. 24
by :: Int -> [a] -> [[a]]
by _ [] = []
by n xs = take n xs: by n (drop n xs)
 
words2 :: String -> (String, String)
words2 str = conc $ words str where
    conc (x:xs) = (x, concat xs)
 
groupTemplates :: String -> [(String, String)]
groupTemplates xs = map (words2) (lines xs)
 
decodeOne :: String -> [(String, String)] -> String
decodeOne _ [] = ""
decodeOne str (x:xs) | str == fst x = fst x ++ " " ++ snd x ++ "\n"
decodeOne str (_:xs) = decodeOne str xs
 
decode :: [String] -> [(String, String)] -> String
decode bs ts = concat $ map (\b -> decodeOne b ts) bs
 
main = do
    bits      <- readFile "bits.txt"
    templates <- readFile "templates.txt"
 
    writeFile "out.txt" $ decode (by 4 bits) (groupTemplates templates)

http://www.cyberforum.ru/haskell/thread723767.html

Запостил: Fai Fai, (Updated )

Комментарии (40) RSS

  • А ещё говорят, что для haskell не нужен yield. Вот шарпик позволяет автоматически закрыть файл и не даст читать из закрытого файла молча как хаскель пустой список. Ну и конечно в шарпике можно не тратить за счет елды память под весь файл.
    Ответить
    • > Вот шарпик позволяет автоматически закрыть файл
      Хаскелевские readFile и hgetContents тоже закрывают файл, когда он дочитается. Другое дело если список до конца не поюзал, тогда закроется только когда GC увидит, что файл никому не нужен.

      > не даст читать из закрытого файла молча
      hClose h
      s <- hGetContents h
      *** Exception: 1.hs: hGetBufSome: illegal operation (handle is closed)

      > Ну и конечно в шарпике можно не тратить за счет елды память под весь файл
      Как-будто тут нужно. hGetContents и readFile - ленивые операции. А если хочется производительности и ленивости - Data.ByteString.Lazy. Читает чанками по необходимости.
      Ответить
      • > hClose h
        > s <- hGetContents h
        Неа, делай так:
        s <- hGetContents h
        hClose h
        print s
        Он тихо прочитает список пустой.
        Ответить
        • Ну и нахуй так делать?

          Once a semi-closed handle becomes closed, the contents of the associated list becomes fixed. The contents of this final list is only partially specified: it will contain at least all the items of the stream that were evaluated prior to the handle becoming closed.

          Есть два правильных варианта использования hGetContents:
          1) Обрабатываешь список до конца и не юзаешь hClose, файл закроется как только ты дойдешь до конца списка.
          2) Обрабатываешь список до куда надо (не забыв подавить ленивость с помощью evaluate, seq и т.п., чтобы все что нужно дочиталось перед hClose), и делаешь hClose руками.

          Если c# и его yield могут сделать что-то кроме этих двух вариантов - запости пруф.
          Ответить
          • В шарпике можно скопировать энумератор и отправить по копии в разные потоки, и они там зачитают что им нужно и потом когда последний энумератор во всех потоках дочитает до конца или раньше выйдет изфорича по причине не нужности дольнейших данных - файл закроется самостоятельно.
            В хаскеле не раздать по потокам не можешь не автозакрыть список, если не читаешь до конца. И надежды 100процентной в хаскеле нет, что файл не весь прочитается в память, а только используемый в данный момент кусок.
            Ответить
            • Здесь ты имеешь в виду, что в шарпике энумератор файла это просто курсор, бегущий по файлу? Ну а нахрена, прости, тогда сувать его в 3 разных потока? Проще и безопасней открыть файл 3 раза в каждом из потоков, и там его и закрыть.

              > И надежды 100процентной в хаскеле нет, что файл не весь прочитается в память, а только используемый в данный момент кусок.
              Прочитается чуть-чуть больше использованного куска. Или для тебя лишние 32 килобайта, прочитанные из-за буферизации уже фатальны?
              Ответить
              • Ну вот хочется тебе открыть эксклюзивно файл, чтобы только твое приложение могло открыть и больше никто. Как ты это сделаешь, если позволишь открывать только одному одновременно. Никак. А вот если открыть исклюзивно в одном месте и раздать курсоры, то ок
                Ответить
                • Предлагаешь разработчикам хаскеля переделать всю подсистему ввода-вывода на асинхронку (не неблокирующее чтение, а именно асинхронное)? Т.к. что на линухе что в винде только так можно одновременно читать и писать один хендл с произвольных смещений несколькими потоками, и .net походу так и делает...

                  Имхо это слишком большая цена за почти никому не нужную иксклюзивность.
                  Ответить
                  • Ну вообщето .нет может читать как асинхроно, так и синхронно. Все на твой выбор. Гугли await. Именно для него в C# 5.0 переписали многие комоненты, чтобы каждый начал поддерживать асинхронность.
                    Ответить
                    • Так, так, так, погуглил насчет волшебных стандартных классов, которые завернут файл в IEnumerable, и решат все мои проблемы позволив мне не задумываясь ни о чем лениво читать один хендл в 100500 потоков, а после этого сами закроют файл... а их нет.

                      Нашел только самодельные быдлоподелия с yield, которые мало того что всяко работают медленнее хаскелевых байтстрингов, так еще и имеют ту же самую проблему с закрытием файла (что-то никакого close/finish я у IEnumerator'а не вижу...).

                      Так что реквестирую пруф для твоего утверждения:
                      когда последний энумератор во всех потоках дочитает до конца или раньше выйдет изфорича по причине не нужности дольнейших данных - файл закроется самостоятельно. Варианты "gc вызовет финализатор когда рак на горе свистнет", и "я закрою его сам" не канают, в хаскеле ведь точно так же.
                      Ответить
                      • P.S. Вариант "его закроет using" тоже не канает, т.к. в хаскеле тоже есть withFile, и это просто синтаксический сахар для ручного закрытия, а меня интересует как реализовать закрытие "когда последний енумератор станет ненужным".
                        Ответить
                          • Хорошая, годная фича, как же я этот метод просмотрел, когда читал доку по енумератору... Тогда описанное выше вполне реально реализовать.
                            Ответить
          • Кстати, ещё забавный момент - казалось бы разворачивание списка должно быть чистым, но оказывается, что оно имеет побочный эффект, тк закрывает файл. чудеса в решете
            Ответить
            • Но ведь и, на первый взгляд чистое, создание тупла имеет побочный эффект в виде выделения памяти, а чистейший оператор сложения излучает тепло в окружающую среду...

              Но да, hGetContents это далеко не лучшая связка между чистым миром хаскеля и нашим полным грязи миром...
              Ответить
      • >Как-будто тут нужно.
        Есть задачи где это нужно

        >Читает чанками по необходимости.
        Только вот чанки эти в памяти сохраняются в том числе и уже не нужные если не быть достаточно осторожным (хотя ты ещё не показал реальной программы, позволяющей это сделать (собирать сборщиком мусора гриву списка)), а ленивый шарпик может не держать в памяти ничего кроме тех блоков, с которыми сейчас работаешь в данный момент и таким образом безпроблем прочитать "в память" 6 гб файл на 32хбитной ос и что-то с ним сделать.
        Ответить
        • >> Как-будто тут нужно.
          Опечатался, сорри, читай как "как-будто тут нельзя".

          Неиспользуемые чанки собираются сборщиком мусора. Не будешь держать спискок за гриву - без проблем обработаются и 6 и 40 и 100 гигов.

          > хотя ты ещё не показал реальной программы, позволяющей это сделать
          На ideone не особо получится из-за таймингов. Ну, впрочем, сейчас напишу код читающий 4 гига из /dev/zero, если оно позволит.

          P.S. Смени ник на HaskellGovno, раз уж о хаскеле говорим.
          Ответить
          • Готов поспорить, что не позволит, тк памяти сборщик мусора сильно нажрет
            Ответить
          • Зерегистрируйся и тайминг будет больше. Кстати вроде идеон не единственый онлайн компилятор хацкеля

            Начнем с простого, а иименно френдли для отпускания хвоста. Сложить все прочитанные байты и вывести результат. Потом нужно подумать над чем-нибдь не френдли
            Ответить
        • > безпроблем прочитать "в память" 6 гб файл на 32хбитной ос

          http://ideone.com/FuxIDo
          время: 5.92s память: 4660 kB
          ЧЯНТД?

          P.S. Не веришь, что читает файл? Запусти у себя с +RTS -s, покажет честно выделенные и освобожденные мусоросборщиком 40 гигов.
          Ответить

Добавить комментарий

Где здесь C++, guest?!

    А не использовать ли нам bbcode?


    8