1. Haskell / Говнокод #20004

    −55

    1. 1
    2. 2
    3. 3
    4. 4
    5. 5
    6. 6
    import qualified Data.ByteString.Lazy.Char8 as BS
    
    readLineOfInts :: BS.ByteString -> [Int]
    readLineOfInts str = case BS.readInt str of
              Nothing -> []
              Just (i, rest) -> i : if BS.null rest then [] else readLineOfInts (BS.tail rest)

    То чувство, когда map read . words не проходит по таймауту.

    Запостил: Yuuri, 14 Мая 2016

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

    • а надо было attoparsec'ом?
      ну и map read . words -- это как раз-таки небезопасное говно
      Ответить
      • Во всяких онлайн-контестах частенько стоит голый GHC с дефолтным набором пакетов :(
        Ответить
    • Некомпозибельно как-то. А как N штук прочитать?
      То ли дело PHP std::cin.
      Ответить
    • Я что-то упоролся, обмазался трансформерами монад и родил вот такое
      -- http://ideone.com/kYGKeX
      module Main where
      
      import qualified Data.ByteString.Char8 as BS
      import Data.Maybe (fromMaybe)
      import Data.Char (isSpace)
      import Control.Monad.State.Lazy
      import Control.Applicative
      
      type Parser a = StateT BS.ByteString Maybe a
      
      data Struct = Struct Int (Int, Int) [Int]
                  deriving (Show)
      
      skipSpaces (x, s) = (x, BS.dropWhile isSpace s)
      
      readInt :: Parser Int
      readInt = StateT $ fmap skipSpaces . BS.readInt
      
      readPair :: Parser (Int, Int)
      readPair = do
        x <- readInt
        y <- readInt
        return (x, y)
      
      readIntList :: Int -> Parser [Int]
      readIntList n = sequence  $ replicate n readInt
      
      readSizedList :: Parser [Int]
      readSizedList = readInt >>= readIntList
          
      orFail = fromMaybe (BS.pack "EPIC FAIL!!!\n")
      
      parsePrint :: Show a => Parser a -> (BS.ByteString -> BS.ByteString)
      parsePrint parseMe = orFail . evalStateT (do x <- parseMe
                                                   return $ BS.pack $ show x ++ "\n")
      
      test = parsePrint (Struct <$> readInt <*> readPair <*> readSizedList)
      
      main = BS.interact test
      Ответить
      • очень всё лениво, из-за чего есть подозрение, что данный код течёт санками и дескрипторами, как крыша ветхой избушки в погожий мартовский денёк
        я бы захуячил парсер интов на продолжениях, к примеру, чтобы можно было разбивать инпут на чанки и потом скормить всё Олегу
        Ответить
        • Show me the code.
          Ответить
          • type Dissector a m r = ∀ x. StateT (Producer B.ByteString m x) (Producer a m) r
            
            ....
            
            parse ∷ (Monad m) 
                  ⇒ A.Parser b
                  → Dissector a m (Either String b)
            parse p = StateT (\s → do
                                n ← lift $ next s
                                case n of
                                  Left _ → return (A.parseOnly p B.empty, s)
                                  Right (o, s') → go s' $ A.parse p o)
              where go s (A.Partial p') = do
                        n' ← lift $ next s
                        case n' of
                          Left _ → return $ (A.eitherResult $ p' B.empty, s)
                          Right (o, s') → go s' (p' o)
                    go s f@(A.Fail l _ _) = return (A.eitherResult f, yield l >> s)
                    go s f@(A.Done l _) = return (A.eitherResult f, yield l >> s)

            ф-ция, преобразующая поток байтов (разбитый на чанки в виде байтстрингов) в поток произвольной хуиты, определяемый парсером p
            в данном случае в качестве Олега выступает Габриэль

            composable, leak-free, const mem*

            *при условии, что размер типа b фиксирован
            Ответить
            • P.S. в последних строчках замечено говно (копипаста), надо будет исправить
              Ответить
            • > в качестве Олега выступает Габриэль

              Кто все эти люди?
              Ответить
              • похоже на либретто Авантазии
                Ответить
              • а что, кроме Киселёва есть ещё Олеги?
                а Габриэль написал pipes
                Ответить
              • мб. этот легендарный олег:
                олег за всё берётся смело
                всё превращается в говно
                а если за говно берётся
                то просто тратит меньше сил
                Ответить
              • Как ныне сбирается вещий Олег
                Отмстить неразумным хозарам,
                Их байты и стринги за буйный набег
                Обрек он мечам и пожарам;
                Ответить
              • > Кто все эти люди?

                Широко известные в узких кругах личности.
                Олег Киселёв - учёный, исследователь, уже лет 20 выносит всем мозг ФП, вот сайт со статьями http://okmij.org/ftp/
                Габриель - Gabriel Gonzalez - ведёт http://www.haskellforall.com/, один из самых вменяемых блогов по Хаски, работает в птиччере.
                Ответить
                • > ведёт http://www.haskellforall.com
                  скандалы, интриги: оказывается он ещё и SJW
                  Ответить
                • А, забыл пояснить, почему "скармливать Олегу" и "в качестве Олега выступает Габриэль".
                  У Олега есть статья, описывающая подход к обработке потоков данных http://okmij.org/ftp/Streams.html
                  Вкратце - это что-то вроде функциональных Boost.IOStreams - источники, приёмники, фильтры. Цель - сделать так, чтобы ленивое IO не текло ресурсами как сито.
                  Желание людей иметь такую штуку настолько велико, что есть несколько независимых реализаций, различающихся во многих деталях.
                  В частности, у Габриэля есть библиотека pipes, которая стремиться к теоретической красоте, у Michael (автор фрэймворка Yesod) - conduits, цель которого - чтобы всё работало.
                  По сути же это всё обычные корутины, которые можно склеивать друг с другом с проверкой типов.

                  Т.е. скармливать Олегу - проталкивать по каналам от источника в приёмники, "в качестве Олега выступает Габриэль" - реализация использует pipes соответствующего автора.
                  Ответить
                • Габриель, Михаель, Йесод, Кабал... че их так к иудейству тянет?
                  Ответить
            • > *при условии, что размер типа b фиксирован
              ** Предложение не является публичной афертой

              > скормить всё Олегу
              А, ты про iteratees, так бы и сказал

              Ну и для контеста многовато писанины.
              Ответить
              • > А, ты про iteratees, так бы и сказал
                не совсем, я в принципе про любую библиотеку из этого семейства
                Ответить

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