1. Куча / Говнокод #12075

    +119

    1. 1
    2. 2
    3. 3
    4. 4
    data Fuuu = Fuuu
    instance Eq Fuuu
     
    main = print $ if Fuuu == Fuuu then "I dosen't seen this" else "and this"

    Вот за что мне нравится сверх надежный высокоуровневый хаскель, так за то, что если забыл переопределить какой-то метод или оператор из класа типов (в нормальных языках это интерфейс или один из базовых класов) стандартной библиотеки языка или неподходящим образом от него отнаследовался, то мы получаем надежное поведение:
    http://ideone.com/6faPct
    результат: Ошибка выполнения время: 0.01s память: 3580 kB сигнал: -1
    ввод: нет
    вывод: нет
    stderr:
    prog: <<loop>>

    Запостил: HaskellGovno, 07 Ноября 2012

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

    • data Fuuu = Fuuu deriving( Eq )
      Ответить
      • Это возможно лишь для некоторых классов из стандартной библиотеки, для которых есть реализация по умолчанию, сгенерированная компилятором. Вот лучшеб вместо встраивания кодогенератора дефолтных реализаций некоторых классов в код компилятора (похоже на хардкод) - лучше бы добавили вменяемые реализации поумолчанию виртуальных функций в саму библиотеку.
        Ответить
        • В темплейт хаскеле есть универсальный Deriving. Не знаю правда насколько универсальный...
          Ответить
          • Вот первый коммент по делу за весь тред. :)
            Можете поподробнее рассказать, а то гуглится обычный хардкодный в компиляторе дерайвинг.
            Ответить
            • http://hackage.haskell.org/package/derive

              Data.Derive is a library and a tool for deriving instances for Haskell programs.

              P.S. Только загуглил. Не читал. Никаких гарантий, что это то.
              Ответить
    • Заебал ты уже своим Хацкилём.
      Заходишь на говнокод - и видишь на главной одно непонятное УГ.
      Ответить
      • Говно из хацкелевских лабораторий так и прёт.
        Ответить
    • >I dosen't seen this
      Лол.


      А сравнение не пашет, потому что ты его не определил. Надо было либо

      data Fuuu = Fuuu deriving (Eq)


      , либо

      data Fuuu = Fuuu
      instance Eq Fuuu
          (==) x _ = x == "Я долбоеб?"
      Ответить
    • Если бы ты внимательно посмотрел на контракт Eq, ты бы увидел, что там объявлены две функции: (==) и (/=). Легко догадаться, что они имеют реализацию по-умолчанию и выражены друг через друга. Не определив ни одной из них, ты получаешь бесконечную рекурсию.

      Если в классе типов есть полиморфные функции без реализации по-умолчанию, компилятор не даст тебе объявить экземпляр, не предоставив реализаций.

      FAIL
      Ответить
      • Ха-ха. В какой раздел Гумно не зайдет - там и обосрётся.
        Только С++ его и терпит.
        Ответить
      • Ох сколько капитанов в треде.
        Цитирую себя:
        > если забыл переопределить какой-то метод, то получаешь следующее поведение
        > забыл
        В случае с Eq это обычно не проблема, тк операторов мало, ты их знаешь и надо быть идиотом, чтобы забыть какой-то, а вот если что-то посложнее - надежный Хаскель покажет дулю во время выполнения перед заказчиком. Могли бы уж запилить контракты на обязательное переопределение хотябы одного метода или не устраивать такую вахканалию.
        Ответить
        • Иметь реализации по-умолчанию очень удобно, можно выбрать именно ту функцию, которую тебе проще всего определить. Такая же фича есть в Scala (можно определять реализации в traits, на этом построены все scala collections), аналогичную фичу вроде хотят ввести в Java 8 для интерфейсов.
          Тут либо удобство, либо паранойная безопасность вместе с кучей бойлерплейта. По мне, первое лучше - в реальной жизни нужно определять всего 1-2 метода, остальное получаешь бесплатно.
          Ответить
          • именно так, но таки считаю, хотябы на уровне стандартной библиотеки, бойлерплейт связанный с контрактами времени компиляции - не злом.

            Не зря же в кресты добавили static_assert и за счет него с кучей бойлерплейта в стандартной библиотеке - часть ошибок сделали или сделают удобочитаемыми или обнаруживаемыми во время компияции. А это как вы понимаете - мейнстрим. Хаскелу и прочим с него стоило взять пример.
            Ответить
            • Поведай мне, как в мейнстримном c++ с помощью волшебного std::static_assert выдать ошибку, если наследник не переопределяет хотя бы одну из виртуальных функций базового класса с реализацией по-умолчанию.
              Ответить
              • А там это не нужно. В стандартной библиотеки крестов себе такого просто не позволяют, чтобы устраивать непотребные зацикленности методов стандартной реализации (крестопринцип). Я тебе даже больше скажу - в стандартной библиотеке крестов дефакто - boost - такого тоже себе не позволяют. Да что уж там. Они даже виртуальные функции стараются не использовать, тк медленно.
                Ответить
                • А было бы удобно, наверное.
                  Ответить
                • Ну так что, хаскелисты снова утонули в своём говне? Кроме того, что я сказал в комментарии к теме, но менее развернуто - никто ничего больше добавить не может? Просто минус без аргументов. Объективненько.
                  Ответить
                  • В стандартной библиотеке крестов и бусте стараются писать классы так чтобы во время компиляции была или ошибка или есть вменяемая реализация по умолчанию для не переопределенных виртуальных методов, а нет такая чтобы происходило зацикливание. Если сказать ни чего аргументированно по проектированию не можете, то приведите хоть контр пример такой библиотеки, где использовался похожий принцип реализации библиотеки как в Хаскеле. Единственное что оправдывает Хаскель, так это то, что он не мейнстрим и проектировался для решения маленьких школьных задач, где подобное проектирование стандартной библиотеки может иметь место.
                    Ответить
    • Эта история произошла со мной, когда мне едва исполнилось 18 лет. Я рос без отца, наверное, поэтому мне не хватало твердости в характере. Я был очень податливым и легко поддавался чужому влиянию.
      Ответить

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