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

    +6

    1. 1
    2. 2
    3. 3
    4. 4
    5. 5
    6. 6
    7. 7
    data Foo a = Foo {a :: a, b :: Int}
               | Bar {b :: Int}
    
    foo :: (a -> b) -> Foo a -> Foo b
    foo f x@Foo{a = a} = x{a = f a}
    foo _ x@Bar{} = x   -- error: Couldn't match type ‘a’ with ‘b’
    foo _ x@Bar{} = x{} -- error: Empty record update

    Рекорды всё-таки дубовые

    cast @HaskellGovno

    Запостил: CHayT, 03 Марта 2018

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

    • Хочу кастовать фантомные типы
      seo #нытьё #ниасилил
      Ответить
    • deriving (Functor) ?
      Ответить
      • В данном упрощённом примере прокатило бы, но далеко не всякий рекорд – функтор.
        Ответить
    • Похоже, ты не первый, кого волнует эта проблема
      https://stackoverflow.com/questions/21649512/coerce-phantom-type
      Проверил, работает
      {-# LANGUAGE RecordWildCards #-}
      module Test where
      
      data Foo a = Foo {a :: a, b :: Int}
                 | Bar {b :: Int}
      
      foo :: (a -> b) -> Foo a -> Foo b
      foo f x@Foo{a = a} = x {a = f a}
      foo _ Bar{..} = Bar{..}
      Ответить
      • Я знаю про это расширение [1]. Оно скоп меняет ещё до кучи, в итоге код становится слишком уж завязанным на него.
        [1] http://govnokod.ru/19959#comment326152
        Ответить
        • Что за пидарская мода? Эти [1] руками вставляются аль скрипт какой?
          Ответить
          • Закос под серьёзную статью со списком литературы.
            Ответить
            • >Эти [1] руками вставляются аль скрипт какой?
              Ответить
            • > Закос под серьёзную статью

              Нет, просто длинные ссылки в параграфе мешают читать текст. В маркдауне что-то похожее есть:

              Link definitions can be placed anywhere in your Markdown document. I tend to put them immediately after each paragraph in which they’re used, but if you want, you can put them all at the end of your document, sort of like footnotes.

              Here’s an example of reference links in action:

              I get 10 times more traffic from [Google] [1] than from
              [Yahoo] [2] or [MSN] [3].

              [1]: http://google.com/ "Google"
              [2]: http://search.yahoo.com/ "Yahoo Search"
              [3]: http://search.msn.com/ "MSN Search"


              Но я, скорее всего, из статей неосознанно подцепил.
              Ответить
              • В маркдауне то может и есть, но я не думал, чт оесть маркдауны, которые это руками набирают, а не в панели кнопками.
                Ответить
                • Набрать 3 символа - непосильный труд.
                  Ответить
                  • 6 символов плюс позиционирование!
                    Ответить
                  • А потом перейти в конец и вставить ссылку туда. Без мышки не обойтись.
                    Ответить
                    • Или дописать текст до конца и только потом вставить ссылку.
                      Ответить
                      • И вспоминать что куда хотел вставить.
                        Ответить
                        • Если тебе памяти не хватает на сраные 2 абзаца - мне тебя жаль.
                          Ответить
                          • А вдруг за личиной Сёмы скрывается смертельно больной, одинокий человек T___T И для него ГК – единственная точка связи с миром T___T Поэтому он настолько толсто всех троллит, чтобы привлечь внимание и продолжать хоть как-то, но общаться T___T

                            Иначе я не могу объяснить, зачем человек может настолько выставлять себя в дураках каждый божий день.
                            Ответить
                            • > смертельно больной
                              Гомосексуализм - не болезнь! Давайте относиться с уважением!
                              Ответить
                              • Давай, давай, а ну, давай,
                                Меня шмонай ты, вертухай,
                                Да загляни под юбочку,
                                Да посмотри на булочки.
                                Понюхай попку носиком,
                                Прикинься, киса, пёсиком,
                                Вот в этом вся и разница,
                                Кто хочет, а кто дразнится.

                                ©Любимая группа мамки админа
                                Ответить
                      • > Или дописать текст до конца и только потом вставить ссылку.

                        я так и делаю обычно, в этом суть. Вставка ссылки это переключение контекста.
                        Ответить
                • показать все, что скрытоvanished
                  Ответить
        • Ты не один такой
          It seems the pragma also turns on some other stuff that I don't want, but if I put this just in the module that defines the transformation functions, it should be safe…
          Конечно, спорить с тем, что records — говно, я не буду.
          Ответить
    • А почему рекорды, чем ситуация отличается от обычного параметризованного типа?
      data Foo a = Foo
       
      foo :: Foo a -> Foo b
      foo x = x -- ошибка

      На месте Foo может быть и [].
      ([]::Int)::Char -- снова ошибка

      Та же питушня:
      template <typename a> class Foo {};
      template <typename a, typename b> Foo<b> foo(Foo<a> x) { return x; }
      
      struct A; struct B;
       
      int main() {
        Foo<B> y = foo<A, B>(Foo<A>()); // error: could not convert ‘x’ from ‘Foo<A>’ to ‘Foo<B>’
        return 0;
      }
      Ответить
      • Просто в записях это особенно раздражает, потому что по стандарту нельзя просто сказать "просто используй структуру другого типа с теми же полями, но другим фантомным типом", что CHayT пытался выразить как "x{}". Придётся явно перечислять все поля из Bar, которых может быть десяток:
        foo _ x@Bar{b = b} = Bar {b = b}
        Ответить
        • > Придётся явно перечислять все поля из Bar, которых может быть десяток:
          Если бы! Ирония в том, что в ванильном Haskell2010 можно добавить _одно_ поле из 10 в record update syntax, и компилятор догадается, чего от него ждут. Но вот логичная попытка заапдейтить 0 полей вызывает ошибку.
          Надо было в сам говнокод это добавить.
          Ответить
          • > можно добавить _одно_ поле из 10 в record update syntax, и компилятор догадается

            ЧЯДНТ?
            foo :: (a -> b) -> Foo a -> Foo b
            foo f x@Foo{a = a} = x {a = f a}
            foo _ x@Bar{b = b} = x {b = b}
            error:
                • Couldn't match type ‘a’ with ‘b’
                  ‘a’ is a rigid type variable bound by
                    the type signature for:
                      foo :: forall a b. (a -> b) -> Foo a -> Foo b
                    at Test.hs:6:1-33
                  ‘b’ is a rigid type variable bound by
                    the type signature for:
                      foo :: forall a b. (a -> b) -> Foo a -> Foo b
                    at Test.hs:6:1-33
                  Expected type: Foo b
                    Actual type: Foo a
                • In the expression: x {b = b}
                  In an equation for ‘foo’: foo _ x@Bar {b = b} = x {b = b}
                • Relevant bindings include
                    x :: Foo a (bound at Test.hs:8:7)
                    foo :: (a -> b) -> Foo a -> Foo b (bound at Test.hs:7:1)
              |
            8 | foo _ x@Bar{b = b} = x {b = b}
              |                      ^^^^^^^^^
            Ответить
            • Лол, ты нашёл ещё один косяк, похоже:
              data Foo a = Foo {a :: a, b :: Int}
                         | Bar {b :: Int, c :: Int}
                         deriving (Show)
               
              foo :: (a -> b) -> Foo a -> Foo b
              foo f x@Foo{a = a} = x{a = f a}
              foo _ x@Bar{b = b} = x{b = b}
              
              main = print $ foo (+1) $ Bar 4 2

              Ошибка, но
              - foo _ x@Bar{b = b} = x{b = b}
              + foo _ x@Bar{c = c} = x{c = c}

              Работает. Вывод типов, похоже спотыкается на полях, пошаренных между конструкторами.
              Ответить
              • Однако! В этом ГК один комментарий удивительней другого.
                Ответить
              • да вы просто для разных паттернов возвращаете разные значения у функции. Foo a когда конструктор Foo и Foo b когда конструктор Bar. Хаскель не виноват, что им пользоваться не умеют.
                Ответить
                • хочешь сказать, что позеры не шарят хаскель?!!!
                  Ответить
    • проблема не в рекордах, а в том, что не надо возвращать саму переменную, если тип результата заявлен как другой
      Ответить

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