Що таке розкол та сплав бананів у функціональному програмуванні?


22

Ці умови згадуються в моєму університетському курсі. Швидкий гуглінг вказав мені на деякі університетські документи, але я шукаю простого пояснення.


@jozefg: Дякуємо за посилання на ваше повідомлення. Одне питання про це. У реченні "Алгебра в цьому сенсі - пара об'єкта C, а карта FC → C.", чи дійсно С повинен бути об'єктом, а точніше категорією? Іншими словами, я не впевнений, чи F позначає функтор у категорії, а F-алгебри - це алгебри, індуковані цим функтором, про те, якщо F - конкретна стрілка від об'єкта на себе.
Джорджіо

Cє об'єктом у певній категорії (скажімо так CC), Fце функтор, CC -> CCтому він відображає CCсебе на себе. Тепер F CC -> CCце лише звичайна стрілка в категорії CC. Отже, Fалгебра - предмет C : CCі стріла F C -> CвCC
Даніель Гратцер

Відповіді:


4

Незважаючи на те, що вже було надано 2 відповіді, я не думаю, що "розщеплення бананів" тут ще не пояснено.

Це дійсно визначено у "Функціональному програмуванні з бананами, лінзами, конвертами та колючим дротом, Ерік Мейєр Маартен Фокінга, Росс Патерсон, 1991"; цю статтю важко читати (для мене) через велике використання Squiggol. Однак "Підручник з універсальності та виразності складки, Грем Хаттон, 1999" містить визначення, яке простіше розібрати:

В якості простого першого прикладу використання складання для генерації кортежів розглянемо функцію підсумкової довжини, яка обчислює суму та довжину списку чисел:

sumlength :: [Int] → (Int,Int)
sumlength xs = (sum xs, length xs)

Шляхом прямого поєднання визначень суми та довжини функцій, використовуючи складку, задану раніше, довжину збору функцій можна переосмислити як єдине додаток згину, що генерує пару чисел зі списку чисел:

sumlength = fold (λn (x, y) → (n + x, 1 + y)) (0, 0)

Це визначення є більш ефективним, ніж оригінальне визначення, оскільки воно робить лише одне обхід списку аргументів, а не два окремі обходи. Узагальнюючи з цього прикладу, будь-яку пару додатків, які можна скласти до одного списку, завжди можна комбінувати для отримання єдиного додатку згортання, що генерує пару, звертаючись до так званої властивості "бананового розколу" fold (Meijer, 1992) . Дивна назва цієї властивості походить від того, що оператор складання іноді записується за допомогою дужок (| |), що нагадують банани, а оператор парування іноді називають розділеним. Отже, їх поєднання можна назвати розщепленням банана!


19

Таким чином, це насправді посилання на документ Meijer та кілька інших під назвою " Функціональне програмування з бананами, лінзами, конвертами та колючим дротом ", основна ідея полягає в тому, що ми можемо приймати будь-який рекурсивний тип даних, як скажімо

 data List = Cons Int List | Nil

і ми можемо визначити рекурсію на змінну типу

 data ListF a = Cons Int a | Nil

Причина, чому я подав заяву, Fполягає в тому, що це зараз функтор! Це також дозволяє нам імітувати списки, але з поворотом: для створення списків ми повинні вкладати тип списку

type ThreeList = ListF (ListF (ListF Void)))

Щоб відновити наш початковий список, нам потрібно тримати це гніздування нескінченно . Це дасть нам тип ListFFде

  ListF ListFF == ListFF

Для цього визначте "тип фіксованої точки"

  data Fix f = Fix {unfix :: f (Fix f)}
  type ListFF = Fix ListF

Як вправу, ви повинні переконатися, що це задовольняє наше вище рівняння. Тепер ми можемо нарешті визначити, що таке банани (катаморфізми)!

  type ListAlg a = ListF a -> a

ListAlgs - тип "списку алгебр", і ми можемо визначити певну функцію

  cata :: ListAlg a -> ListFF -> a
  cata f = f . fmap (cata f) . unfix

Далі більше

  cata :: ListAlg a -> ListFF -> a
  cata :: (Either () (Int, a) -> a) -> ListFF -> a
  cata :: (() -> a) -> ((Int, a) -> a) -> ListFF -> a
  cata :: a -> (Int -> a -> a) -> ListFF -> a
  cata :: (Int -> a -> a) -> a -> [Int] -> a

Вигляд знайомий? cataточно так само, як і праві складки!

Що насправді цікаво, це те, що ми можемо робити це більше, ніж просто списки, будь-який тип, який визначений цим "фіксованою точкою функтора", має, cataі щоб вмістити їх усе, нам просто потрібно розслабити підпис типу

  cata :: (f a -> a) -> Fix f -> a

Це насправді натхнене з фрагмента теорії категорій, про який я писав , але це м'ясо сторони Хаскелла.


2
варто відзначити , що банани (| |) дужка , що оригінальні паперу використовують щоб визначити Cata
JK.

7

Хоча Йозефг дав відповідь, я не впевнений, чи відповів він на питання. "Закон плавлення" пояснюється в наступній роботі:

Навчальний посібник про універсальність та виразність складок, ГРАХАМ Хаттон, 1999

В основному це говорить про те, що за деяких умов ви можете поєднати ("запобіжник") функції функції і скласти в одну складку, так що в основному

h · скласти gw = скласти fv

Умови цієї рівності є

hw = v
h (gxy) = fx (hy)

"Закон про банановий розкол" або "закон про розкол бананів" - із статті

Функціональне програмування з бананами, лінзами, конвертами та колючим дротом, Ерік Мейєр Маартен Фокінга, Росс Патерсон, 1991

На жаль, статтю дуже важко розшифрувати, оскільки в ній використовується формалізм Птах-Мертенс, тому я не зміг зробити її головою чи хвостом. Наскільки я зрозумів "закон про розкол бананів", він говорить, що якщо у вас є два складання, що працюють на одному аргументі, їх можна об'єднати в одну складку.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.