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

    +119

    1. 1
    foldr ((.) . (:)) id

    Запостил: HaskellGovno, 20 Мая 2012

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

    • Типичный код хаскелиста. Ломайте мозг, отвечайте, что делает код. Творожок ждет своего победителя.
      Ответить
      • Омг, конкатенация списка. По списку генерит функцию, прицепляющую оный в начало другого.
        Ответить
      • творожок, бугого!
        Ответить
    • Пытаюсь понять ваще.
      Как можно операцию прикрепления элемента к голове (возвращающую список) композиционировать с операцией композиции (принимающей две функции)?
      Ответить
      • Таки частичное применение
        вот тип выражения, может, поможет:
        Prelude> :type (.) . (:)
        (.) . (:) :: a -> (a1 -> [a]) -> a1 -> [a]
        Prelude> let f = foldr ((.) . (:)) id
        Prelude> :type f
        f :: [a] -> [a] -> [a]
        Prelude> :type foldr
        foldr :: (a -> b -> b) -> b -> [a] -> b
        Ответить
        • foldr :: (a -> b -> b) -> b -> [a] -> b
          (.) . (:) :: a -> (a1 -> [a]) -> a1 -> [a]   ~ (a -> b -> b)
          где a = a, b = a1 -> [a]
          т.е. в результате получаем функцию, которая принимает на вход элемент и функцию, возвращающую список, и возвращает новую функцию, возвращающую список
          Ответить
          • > т.е. в результате получаем функцию, которая принимает на вход элемент и функцию, возвращающую список, и возвращает новую функцию, возвращающую список

            > В печальном итоге получаем функцию, которая первым параметром принимает подклеиваемый элемент x, вторым аргументом - некую функцию h с одним параметром, и возвращает функцию, которая при вызове с параметром y вызовет функцию h и приклеит к результату в начало x.

            Основной недостаток ФЯ - хрен объяснишь словами что тут происходит. У императивных такие объяснения выглядят попроще :)
            Ответить
            • Это точно :)
              Однако умные дядки в хороших книжках как-то умудряются раскладывать по полочкам даже самый замудрёный матан. Бесконечно уважаю таких людей.
              Ответить
              • Читал когда-то "Введение в функциональное программирование", John Harrison. Всё подробно расписано, лямбды, исчисление Чёрча и пр.
                Однако, фраза во второй главе книги: "Когда Карри ознакомился с работами Шейнфинкеля, он предпринял попытку с ним связаться, но к этому времени Шейнфинкель оказался в психиатрической лечебнице" как-то слегка напрягла :))
                Так что мало разложить по полочкам, нужно ещё суметь не сойти с ума.
                Ответить
                • Да, а ещё Хаскелл называли безопасным языком, по сравнению с сишкой...
                  Ответить
                  • Типа с сишкой отделаешься простреленной ногой, а будешь водиться с функциональщиками - умом тронешься?
                    Ответить
                  • Хаскел чист и безопасен. Он только возвращает IO экшен из main'а :) Вся грязь в его рантайме.
                    Ответить
      • Ну попробуем так - композиция это, говоря математически, (.) f g = \x -> f (g x). Т.е. получается функция с одним аргументом, которой последовательно пропускается через функции g и f.

        Первой функцией у нас является (:), пропустив через него аргумент получим (x:) - функцию, которая приклеивает элемент x в начало списка.

        Второй функцией является композиция (.). Первым аргументом ее будет функция (x:). Получится функция, принимающая функцию от одного аргумента, которая вызывает ее, передавая результат (x:), т.е. приклеивая элемент к результату.

        В печальном итоге получаем функцию, которая первым параметром принимает подклеиваемый элемент x, вторым аргументом - некую функцию h с одним параметром, и возвращает функцию, которая при вызове с параметром y вызовет функцию h и приклеит к результату в начало x.

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

        P.S. Проще и понятнее было бы записать все это в виде формулок, но это скучно :)
        P.P.S. Объяснение хреновое, я знаю :(
        Ответить
        • >В печальном итоге получаем
          А почему в печальном? Наоборот весело же. :)
          Ответить
        • Я чувствую себя таким тупым...
          Но короче да, я понял, я ошибся, сразу применив : к двум аргументам, получая на выходе список, а не функцию.

          > и возвращает функцию, которая при вызове с параметром y вызовет функцию h и приклеит к результату в начало x.

          Не наоборот? (f.g)(x) = f(g(x)) же, я так понял?
          (извините за быдлятскую запись функции через скобочки)
          Ответить
          • Композиция в (f.g)(x) = f(g(x)) правильно расписана. Но (x:) попадает левым параметром (т.е. на место f). А правый параметр остается свободным - в него и попадет функция h, поэтому она вызовется первой, а (x:) второй.
            Ответить
            • Ладно, короче я сначала должен попытаться понять, что означают сиськи вот эти:
              (.) . (.)
              Ответить
              • А к этим сиськам лучше подойти формально (см. мой пост http://govnokod.ru/10331#comment138654, там в первом блоке расписано во что она раскроется).

                А получаем мы чето типа такого:
                ((.) . (.)) f a b c = f (a b c)


                Аналог на C:
                int tits(void (*f)(int a, int b, int c), int a, int b, int c)
                {
                  return f(a, b, c); 
                }
                Ответить
                • >Аналог на C:
                  Не, ну мне больше нравится аналог на си или хотя бы Хаскелевый (\f a b c = f (a b c)), чем сиськи.

                  Но конечно вариант (.) . (.) больше подходит для того что бы похвастаться во дворе перед ребятами, мол я у хаскеля сиськи потрогал.
                  Ответить
                  • Если это внутренности (вроде в исходниках fgl встречалось) - то нормально.
                    Или если если присутствует коммент с явным видом (но лишняя строчка для поддержки).
                    А в целом, скобочки рядом с "." - моветон. \f g x -> f . g x - еще читабельно.
                    Ответить
              • А вот кстати сиськи марсианской шлюхи из "Вспомнить все":
                (.) . (.) . (.)


                Воистину на Хаскелл можно написать что угодно.
                Ответить
                • Занимательно, что обычные сиськи: (.) (.) == (.) . (сиськи амазонки-левши),
                  а сиськи HaskellGovno: (.) . (.) == (.) (.) (.)
                  Ответить
                • Вот только проблема с этими сиськами в том, что они слишком ленивы чтобы прыгать когда марсианская шлюха бежит, поэтому ей приходится шлепать по ним руками. Сиськи три, а руки-то две, проблема!
                  Ответить
                • А точка входа имеет тип монады ввода-вывода, все по Фрейду, все как у людей.
                  Ответить
    • Астрологи объявили неделю хаскеля. Количество сисек на говнокоде удваивается.
      Ответить

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