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

    +124

    1. 1
    2. 2
    3. 3
    4. 4
    5. 5
    data Trivalent = TriFalse | TriUnknown | TriTrue deriving (Show, Eq, Ord)
    
    (&) :: Trivalent -> Trivalent -> Trivalent -- &&
    (!) :: Trivalent -> Trivalent -> Trivalent -- ||
    nt :: Trivalent -> Trivalent -- not

    В хасскеле нет класса для логических значений. А значит хрен переопределишь операторы &&, || и функцию not

    Запостил: Fai, 08 Ноября 2012

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

    • (!) зря определил, это индексирование массивов.
      Ответить
      • Разве не (!!)?
        Ответить
        • !! для списков
          Ответить
          • Значит монадами изучение хаскелла не закончилось... Пойду читать RWH...
            Ответить
            • Именно. Там гигантская библиотека забортом осталась. Одних массивов там несколько штук с разными интрфейсами. А ведь массивы - самая простая структура данных. Так что впереди увлекательный мир нестриженной бороды.
              Ответить
    • Еще один. Ждем-с когда появится Роман а-ля deus ex machina и разъяснит что неосилено топикстартером на этот раз.
      Ответить
      • Заменю Романа, пока он отсутствует.

        > Хрен переопределишь:
        http://ideone.com/nG59NT
        Ответить
        • За
          import Prelude hiding ((&&), (||), not)
          спасибо.
          Ответить
        • К слову операторы || и && определяются проще. Если тип Ord и Eq, и False < Unknown < True, то
          x || y = max x y
          x && y = min x y

          Ну а not проще никак не сделать.
          Ответить
      • > что неосилено топикстартером

        А то, что я правильно написал - класса Logical c операторами && || not - нет! Num - есть, Fractional - есть, Integral - есть, Eq, Show, Read, Ord и т.д. и т.п - всё есть.

        А класса для реализации произвольной логики - нет! Есть всего-лишь недотип data Bool...
        Ответить
        • На тебе класс.
          http://ideone.com/rXQ0lw
          Ответить
          • -____________________-
            Ответить
          • Вот именно за это мне нравятся type classes. Это просто шикарно:
            import Prelude hiding ((&&), (||), not)
            import qualified Prelude
             
            infixr 3  &&
            infixr 2  ||
            infixr 3  `xor`
             
            class Boolean a where
                (&&) :: a -> a -> a
                (||) :: a -> a -> a
                not :: a -> a
             
            data Trivalent = TriFalse | TriUnknown | TriTrue deriving (Show, Eq, Ord)
             
            instance Boolean Trivalent where
                TriFalse && _ = TriFalse
                _ && TriFalse = TriFalse
                TriTrue && TriTrue = TriTrue
                _ && _ = TriUnknown
                TriTrue || _ = TriTrue
                _ || TriTrue = TriTrue
                TriFalse || TriFalse = TriFalse
                _ || _ = TriUnknown
                not TriTrue = TriFalse
                not TriFalse = TriTrue
                not TriUnknown = TriUnknown
             
            instance Boolean Bool where
                (&&) = (Prelude.&&)
                (||) = (Prelude.||)
                not = Prelude.not
             
            xor :: Boolean a => a -> a -> a
            a `xor` b = not a && b || not b && a
             
            main = do
                print $ TriTrue && TriFalse
                print $ not (TriFalse || TriUnknown)
                print $ not (TriUnknown || TriFalse && TriTrue)
                print $ 2 < 3 `xor` False
                print $ map (&& TriTrue) [TriTrue, TriFalse, TriUnknown]
                print $ map (&& True) [True, False]
            Мне остаётся только восхищаться.
            Ответить
            • Тут еще проблема есть. Нельзя использовать операции, принимающие два разных типа из одного тайпкласса. Даже с числами в стандартной библиотеке эта проблема существует. И решается она походу только всякими toXxx да fromXxx
              Ответить
              • Да, такое есть, но на фоне такой же строгой системы типов F#, но без тайпклассов это смотрится просто прекрасно. Хаскель когда решил уровнение с типами - он вывел 10ть нужных тайпклассов для данной переменной и как бы ок. А какой-нибудь F# вывел тебе int и ты уже с ним ничего не сделаешь универсального. Он есть int и все, приехали. В какой нибудь функции ты уже не можешь указать, что тебе нужен лишь интерфейс Eq (в Хаскеле обычно этот Eq сам хаскель выведет). Эта функция в F# должна будет принять конкретно int, а иначе пошлет тебя компилятор. Или опять же ты не можешь написать map f list1. Тебе придется написать List.map f list1. Опять же это из-за того, что нет тайпклассов. Система тайпклассов я считаю гениальна. Эта типизация хаскелю подходит как нельзя лучше.
                Ответить
                • Вообщем в F# настолько ублюдочная типизация, поэтому я считаю, что она не достойна даже, чтобы я на ней писал говно или постил на уютненький говнокод.
                  Ответить
                  • >она не достойна даже, чтобы я на ней писал говно
                    Какое у тебя самомнение. Лучше вообще не пиши говно, ок?
                    Ответить
                    • >Какое у тебя самомнение.
                      Не. Это мнение о типизации слишком низкое. Рядом есть много более перспективных типизаций, а майкрософт выбрала самую простую и кривую.
                      Ответить
                • > Хаскель когда решил уровнение с типами
                  Помнится, кто-то катил бочку на Хиндли-Милнера

                  > Хиндли-Милнер - детский сад и в Немерле не применяется
                  http://govnokod.ru/11658#comment152370
                  Ответить
                  • 0) Надо же, помнишь.
                    1) В Хаскеле вроде модификация Хиндли-Милнера, в отличие от F#, где он более чистый.
                    2) Я сказал, что эта типизация подходит Хаскелю. Типизация ~= система типов + система вывода типов.
                    Так вот в Хаскеле система вывода типов очень сочитается с системой типов. Очень хорошая подборка связки. Не побоюсь этого слова, очень хороший ученый поработал. Это тот случай когда среди ограничений рождается что-то принципиально новое и сильное.
                    3)Ну да, Немерловый вывод типов много сильнее Хиндле-Милнера за счет того, что система типов .НЕТ используется в полной мере со всеми перегрузками, промоутингом и приведениями типов.

                    То есть вывод типов Хиндле-Милнер становится сильным только из-за правильно инженерно подобранной достаточно простой типизации в Хаскель. F# с Хиндле-Милнером сразу идет лесом, тк типизация используется из .НЕТ, но при этом убого ограниченная и не продуманная (как например в Хаскеле с её классами типов). Ну а в Немерле очень мощный вывод типов, тк работает с типизацией обычного C# без каких либо ограничений или специальной продуманнасти типизации как в Хаскеле. А стандартному Хиндле-Милнеру это и не снилось, что мы и видем на примере F#. Вывод типов F# просто не способен работать с типизацией уровня С#.
                    Ответить
            • З.ы. копипастить мой код было совершенно необязательно. Кому он нужен - прочел бы и на ideone.
              Ответить
              • Ну я боюсь, что идеон стирает старые говнокоды, а так тут может сохранится. :-[
                Ответить
                • Аккаунт уже там заведи.
                  Ответить
                  • Да кстати, надо бы и мне завести учетку. А то клонирую коды десятками, если прямо там пытаюсь пилить.
                    Ответить
                    • Заодно дают возможность делать ограничение по времени 15 секунд.
                      Ответить
                      • А это плохо. Нет челленджа при отправке долго работающего кода.
                        Ответить
            • > Мне остаётся только восхищаться.

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

              Я бы сказал в хаскелле всё-всё-всё элегантнее, а монады это лучший способ инкапсуляции состояния.
              Ответить
              • >а монады это лучший способ инкапсуляции состояния.
                А почему вы так считаете? Мне что-то он не слишком понравился. Но надо мне ещё поработать с Хаски, чтобы составить более полное и аргументированное мнение.
                Ответить
                • Просто у меня за множество лет программирования сложилось понятие об идеальном языке программирования (замечу, задолго до того как я даже услышал про хаскелл):

                  1. Только строгая статическая типизация.
                  2. Никаких неявных преобразований, даже безопасных.
                  3. Удобная запись типов.
                  4. Удобный синтаксис шаблонов.
                  5. Кроссплатформенность.
                  6. Надёжность.
                  7. Ортогональность. Я ненавижу глупые исключения из правил.
                  8. Комбинируемость всех конструкций.
                  9. Элегантная и краткая форма записи.

                  Как видно Хаскелл подошёл по всем параметрам:
                  1. В хаскелле строгая статическая типизация.
                  2. В хаскелле нет неявных преобразований.
                  3. [a] и (a -> b) намного удобнее чем "std::vector<a>" и "b foo<a>" (сравнение не точное, но суть не меняется).
                  4. foo :: a -> a
                  5. GHC и Haskell Platform есть под Win, Mac, Lin.
                  6. За счёт строгой типизации, автовывода типов и чистоты хаскелл надёжнее чем все эти джавы вместе взятые.
                  7. Единственное исключение, найдённое мною в хаскелле - патерн-матчинг не позволяет использовать выражения вроде:
                  intsqrt( x^2 ) = x
                  8. ВСЁ КОМБИНИРУЕТСЯ. Тоесть вообще всё!
                  9. Код на хасскеле короче чем на перле и понятнее чем на питоне!

                  Есть только два недостатка, которые меня действительно волнуют - неполноценность типа Bool в стандартной библиотеке (хотя всё это решается) и отсутствие исчерпывающего учебника на русском языке.
                  Ответить
                  • > неполноценность типа Bool
                    MayBe Bool, нэ?
                    Ответить
                    • Just True && Nothing = ???
                      Ответить
                      • Если разберешься с аппликативными функторами, то ответ не заставит себя ждать.
                        http://ideone.com/9LL4Ah
                        Изучай систему типов и стандартную библиотеку. А трибулы (а темболее велосипедные) это костыли.
                        Если конечно, у тебя не чуть ли вся программа на них построена, то конечно и они могут иметь место.
                        Ответить
                        • С этим то я разобрался, но неудобно же.
                          Ответить
                        • > Если разберешься с аппликативными функторами, то ответ не заставит себя ждать
                          > Изучай систему типов и стандартную библиотеку

                          Why so didactic?
                          Ответить
                        • Ох и кстати.
                          (||) <$> Just True <*> Nothing == Nothing

                          Хотя в троичной логике
                          True || Undefined == True
                          Ответить
                  • > За счёт строгой типизации, автовывода типов и чистоты хаскелл надёжнее чем все эти джавы вместе взятые.
                    Столкнешься с ленивым вводом-выводом, еще вспомнишь свои слова о надежности.

                    > Код на хасскеле короче чем на перле и понятнее чем на питоне!
                    А вот тут неправда. Функциональный код то короче, но когда пытаешься писать императивщину - то длиннее, и отступы быстро наматываются.
                    Ответить
                  • 2, 5 - это реализация, а не язык: поскольку говорится о "идеале", то эти сущности стоит разделять

                    > 2. В хаскелле нет неявных преобразований.
                    что вы понимаете под ними, а то в том же ghc есть rewrite-rules

                    > 5. GHC и Haskell Platform есть под Win, Mac, Lin.
                    есть и аппаратная сторона, с тем же армом еще проблемы

                    > 7. Единственное исключение...
                    это уже вне сопоставления по образцу, а скорее в сторону пролога

                    > 9. Код на хасскеле короче чем на перле и понятнее чем на питоне!
                    очень спорно

                    > Есть только два недостатка, которые меня действительно волнуют...
                    "i have bad news for you", скорее это высокии барьер (что, впрочем, проблема экосиситемы, а не языка); сложно предсказуемая эффективность: незначительные изменения в коде могут кардинально влиять на производительность, нехватку или избыточность ленивости довольно тдудно выловить
                    Ответить
                • Ещё добавлю, что до хаскелла почётное первое место занимал питон, который подходит по большей части пунктов (но не по всем).

                  Реальный код всё-равно приходится писать на си/плюсах/ас3/жабе...
                  Ответить
                  • > Реальный код всё-равно приходится писать на си/плюсах/ас3/жабе...
                    PHP...
                    Ответить
              • Кстати, поправьте меня, если я не прав, но кажется, я разглядел в плюсах тайпклассы
                http://ideone.com/5tA9Ne
                Ответить
                • Похоже кстати.
                  Ответить
                • Я вот начинаю думать, что вы правы и ситуация довольно близка. Я поэксперементировал (хотя надо бы ещё). Похоже typeclasses не содержит виртуальных функций. Например функции принимающие "тип_класса тип => конструктор_типа тип" похоже принимают эту функцию не как интерфейс с виртуальными функциями, а как шаблон (из крестов) с ограничениями (where в генериках C#). То есть это все вполне может работать очень оптимизированно. Наверное благодаря этому Хаскель такой быстрый. Виртуальные функции похоже появляются только после применения предиката форол: "forall тип. тип_класса тип => конструктор_типа тип". Надо конечно над всем этим ещё поразмышлять, но похоже все именно так.
                  Ответить
                  • Наверное благодаря этому Хаскель такой быстрый *.
                    * По сравнению с python и javascript
                    Ответить
                    • Хаскель традиционно раза в 2-3 медленее сишечки. Имхо очень круто для очень высокоуровнего языка.
                      Ответить
                      • Хаскель* традиционно раза в 2-3 медленее сишечки**.

                        * Если программист опытный.
                        ** Если программист нуб или оптимизация по времени не требовалась.
                        Ответить
                  • *Например функции принимающие параметер типа "тип_класса тип => конструктор_типа тип" похоже принимают этот параметер не как интерфейс с виртуальными функциями, а как шаблон (из крестов) с ограничениями (where в генериках C#).
                    selfix ночных посиделок
                    Ответить
    • В качестве домашнего задания реализовать 9ти стабильный булеан программистов FPGA STD_LOGIC_1164:
      http://en.wikipedia.org/wiki/IEEE_1164
      Ответить
    • И ещё не забудь добавить вероятностный (не чёткий) булеан.
      Ответить

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