thedeemon: (office)
[personal profile] thedeemon
Посмотрел тут свежее выступление известного программиста компьютеров в гамаке Р. Хики. Доклад про трансменьшители.

Помните, во всяких учебниках про ФП есть упражнения по выражению различных функций над списками через fold? Почему именно через fold, а не что-то другое? Да потому что это Котоморфизм Всемогущий: тот самый уникальный морфизм, что идет от инициального объекта к каждому другому, в данном случае в категории алгебр заданного эндофунктора. Ведь что такое список с элементами типа Е? Каждое его значение это либо константа 1 (Nil, [] - ей изоморфны), либо пара (произведение) из Е и аналогичного списка - хвоста. Т.е. 1 + Е*Х. Берем функтор F(X) = 1 + E*X. Нам нужна рекурсивная конструкция, чтобы вместо Х везде был "список из Е", а значит надо ListE = 1 + E * (ListE) = F(ListE). Раз получили ListE = F(ListE), значит нужна неподвижная точка. Построить ее несложно:
newtype Fix f = Fx (f (Fix f))
и для конструктора Fx можно сразу записать обратную функцию
unFix :: Fix f -> f (Fix f)
unFix (Fx x) = x

Для всякого эндофунктора F и типа Т, если взять функцию alg: F T -> T, то такая тройка из F, T, и alg называется F-алгеброй. Если F - функтор, т.е. в интересующей нас категории это конструктор типов, то Fix F - уже просто тип, вполне конкретный для данного функтора. Подставив его вместо Т в определение F-алгебры, получим F-алгебру (F, Fix F, alg : F (Fix F) -> Fix F). Сравнив тип alg и Fx выше, видим, что Fx и есть такая алгебра. Утверждается, что эта алгебра для F особенная: она инициальная, т.е. служит инициальным объектом в категории F-алгебр для F, т.е. для любой другой алгебры в нем, т.е. любой пары из типа Т и функции alg : F T -> T существует функция g из инициального объекта Fix F в T. Да такая, что вот эта диаграмма коммутирует, т.е. оба пути из f (Fix f) в Т эквивалентны:

Почему такая g существует? Да потому что мы можем взять обратную для Fx функцию unFix, и просто определить g как композицию из unFix, fmap g и alg:

Поскольку g зависит от alg, опишем это как функцию g = cata alg:
cata :: Functor f => (f a -> a) -> Fix f -> a
cata alg = alg . fmap (cata alg) . unFix

Это работает для произвольного эндофунктора, так можно опрелять самые разные рекурсивные индуктивные типы, и катаморфизм для них всегда будет работать сверткой: он позволяет из значения рекурсивного типа (скажем, AST-дерева или списка) получить значение произвольного типа (например, строку), если есть функция-алгебра, умеющая делать один шаг свертки. Например, если у нас есть список интов, и мы хотим его превратить в строку, то
E = Int
F(X) = 1 + Int * X
List_Int = Fix F = 1 + Int * List_Int
T = String
alg : F T -> T = 1 + Int * String -> String
т.е. alg должна уметь делать строку из ничего (1, пустой список) и из пары элемент * строка, где та строка получена из хвоста списка этой же операцией рекурсивно. Передав такую алгебру в котоморфизм cata, получим функцию Fix f -> a т.е. List_Int -> String. Узнаете? Этот котоморфизм и есть foldr для списка! Все, что можно сделать из списка (по крайней мере операциями вроде alg - берущими по одному элементу и некоторым образом наращивающими свой результат), можно сделать fold'ом. Более того, если мы хотим выразить алгебраический тип в языке без оных но с функциями, можно использовать Church encoding или типизированный Boehm-Berarducci encoding, и результат будет выглядить точно как тот fold. А алгебра, что передается в катаморфизм, получила у Хики новое имя - reducerинновация!.

Ну так вот, увидел Хики, что fold это хорошо, но заметил, что реализуя через него операции над списками мы почему-то используем конструкторы списка. А при реализации оных для векторов - конструкторы векторов. Непорядок, недообобщение!



Только один-то конструктор он заметил, а про второй забыл:



Если conj заменить на построитель не-векторов, а [] оставить, будет банальная ошибка типов. В этой его кложури - еще и в рантайме. Ибо про функторы с алгебрами не думал, там-то тип сразу показывает о каких вариантах надо заботиться. Ну и предложил абстрагироваться, вынести конструктор из кода в параметр:



Получилось, что внутри там функция принимает такой конструктор (вроде cons или conj), фрагмент алгебры, a.k.a. reducer, и возвращает такой же. Ну а функции вида Хрень -> Хрень хорошо композятся. Придумал для такого преобразования reducer -> reducer новое имя: transducerинновация!. Но поскольку половину алгебры он в самом начале потерял, в таком виде оно не работает, конечно. Пришлось добавлять хаки. Хак первый: писал он на кложури, а она позволяет функции принимать разное число аргументов и в зависимости от этого вести себя по-разному. Ну и сделал, что ежели аргументов не дали, то пусть работает как вторая половина алгебры: пусть возвращает значение, соответствующее пустому списку. А еще захотел уметь прерывать обработку, не доходя до конца списка. Всякие хаскели это в foldr делают легко за счет ленивости: не обращайся к вычисленному хвосту, он и не будет вычисляться. А в кложури все иначе, поэтому сделал сигналирование о конце заворачиванием значения в специальную обертку, такой вот модный динамически-типизированный способ передать булев флаг. Ну и сделал третий вариант функции от двух аргументов, принимающий лишь один аргумент, в таком случае там она что-то сигналирует. В результате то, что выглядит как композиция функций, есть композиция троек функций (от 0, 1 и 2 аргументов), работающих с неожиданно типизированными вещами. Теперь весь мир побежал это дело переписывать на другие языки. Но мы-то знаем, что, учитывая форму этих алгебр-уменьшателей, речь все равно только о списках и эквивалентных им вещах, и поскольку среди всех таких структур список - самый общий (свободный моноид, панимаиш), то все эти трансменьшители сводятся к такому типу:
transducer: [a] -> [b]

Зато инновации!

Date: 2014-09-21 09:55 am (UTC)
From: [identity profile] jamhed.livejournal.com
Не хватает писателям языков формального образования?

Date: 2014-09-21 03:30 pm (UTC)
From: [identity profile] sassa-nf.livejournal.com
причём, это они всего лишь таблицу умножения, так сказать, не усвоили.

Date: 2014-09-21 10:15 am (UTC)
From: [identity profile] justy-tylor.livejournal.com
Сначала прочитал как "трансмешители", и считаю такое прочтение более удобным. И с образом Янковица гармонирует. :)

Date: 2014-09-21 12:15 pm (UTC)
From: [identity profile] voidex.livejournal.com
trancducer™ : [a] → [b]

Date: 2014-09-21 12:19 pm (UTC)
From: [identity profile] nivanych.livejournal.com
Годно, категорно-расово верно! ;-)
Немноожечко не хватает понятия (ко)алгебр над (ко)монадой и рассказа о топосах этих (ко)алгебр в топосе.
Если монада T над неким топосом имеет правый сопряжённый, то категория T-алгебр (над этой монадой) — топос.

Date: 2014-09-21 12:25 pm (UTC)
From: [identity profile] sassa-nf.livejournal.com
"Почему такая g существует? Да потому что мы можем взять обратную для Fx функцию unFix, и просто определить g как композицию из unFix, fmap g и alg"

ой. существование g определено через существование fmap g...

Там сложнее, и необходимо не просто unFix, а именно изоморфизм, а от функтора требуется сохранение пределов. Функция g существует как раз из-за сохранения пределов.

Date: 2014-09-21 12:30 pm (UTC)
From: [identity profile] thedeemon.livejournal.com
Спасибо! А хаскелю вон хватает того конструктивного доказательства, что приведено. Построили - стало быть существует, хоть и рекурсия там.

Date: 2014-09-21 02:50 pm (UTC)
From: [identity profile] sassa-nf.livejournal.com
а в CCC эндофункторы сохраняют пределы :)

или может лучше сказать, что полиномиальные эндофункторы сохраняют пределы (а в х-е все функторы полиномиальные)
Edited Date: 2014-09-21 02:51 pm (UTC)

(no subject)

From: [identity profile] thedeemon.livejournal.com - Date: 2014-09-26 12:08 pm (UTC) - Expand

(no subject)

From: [identity profile] sassa-nf.livejournal.com - Date: 2014-09-26 02:28 pm (UTC) - Expand

(no subject)

From: [identity profile] thedeemon.livejournal.com - Date: 2014-09-26 03:16 pm (UTC) - Expand

(no subject)

From: [identity profile] sassa-nf.livejournal.com - Date: 2014-09-26 03:26 pm (UTC) - Expand

(no subject)

From: [identity profile] thedeemon.livejournal.com - Date: 2014-09-26 03:54 pm (UTC) - Expand

(no subject)

From: [identity profile] sassa-nf.livejournal.com - Date: 2014-09-26 04:07 pm (UTC) - Expand

(no subject)

From: [identity profile] sassa-nf.livejournal.com - Date: 2014-09-26 04:13 pm (UTC) - Expand

Date: 2014-09-21 03:50 pm (UTC)
ext_659502: (Default)
From: [identity profile] some41.livejournal.com
Data.Foldable?

Date: 2014-09-21 04:42 pm (UTC)
From: [identity profile] juan-gandhi.livejournal.com
Я вообще уже задумываюсь, ездить ли на стрейнджлуп в следующем году.

Раньше там и Хики красиво выступал, и Киселев бывал, и Мейер.

Ну, правда, было же в этом году некоторое количество хаскельщиков и скальщиков; эти-то по делу выступали.

Date: 2014-09-21 05:23 pm (UTC)
From: [identity profile] vshabanov.livejournal.com
Несколько раз натыкался на хвалебные речи о Хикки и думал, что же в них не так. Теперь понял -- они мне подозрительно напоминали описание "гениальных" изобретателей гербалайфов или пылесосов кирби. Похоже, Хикки -- один из них.

Date: 2014-09-21 05:50 pm (UTC)
From: [identity profile] thedeemon.livejournal.com
Ну, все же следует признать, что эта его кложура работает и делает кого-то счастливым. Люди в этом что-то находят, и что-то практичное делают. Кто опердени, кто чаты для котиков. Ересь это или альтернативная секта - вопрос открытый. :)

Date: 2014-09-21 05:54 pm (UTC)
From: [identity profile] maxim.livejournal.com
Безжалостный троллинг.

Date: 2014-09-21 07:28 pm (UTC)
From: [identity profile] Колмогорова Простота (from livejournal.com)
Пока что как следует не разобрался с темой, но вроде бы, грамотно реализованные на хаскеле трансдюсеры иногда всё-таки могут иметь некоторый смысл. Например, внутренние промежуточные шаги вычисления могут запускаться с любыми подходящими структурами данных и вместо списка там можно вставить нечто более-эффективное-в-таком-то-конкретном-случае.

Интересные ссылки:
http://conscientiousprogrammer.com/blog/2014/08/07/understanding-cloure-transducers-through-types/ (см. "the fact that munge actually internally uses a list" - example2)
http://www.reddit.com/r/haskell/comments/2cv6l4/clojures_transducers_are_perverse_lenses/cjjiasy
Edited Date: 2014-09-21 07:54 pm (UTC)

Date: 2014-09-21 08:09 pm (UTC)
From: [identity profile] Колмогорова Простота (from livejournal.com)
Например, если есть что-то в духе "nub ... concatMap", то, благодаря трансдюсерам, можно сделать просто flatmapping с результатом в Set вместо списка и даже не писать нигде Set.fromList/Set.toList.

Date: 2014-09-22 09:10 am (UTC)
From: [identity profile] voidex.livejournal.com
А каким образом будет выражено, что результат - Set?
Edited Date: 2014-09-22 09:10 am (UTC)

Date: 2014-09-22 10:16 am (UTC)
From: [identity profile] Колмогорова Простота (from livejournal.com)
Ну вот по первой ссылке в моём соседнем посте есть такое:
flatmapping :: Foldable f => (a -> f b) -> Transducer b a
и там делается
flatmapping (\x -> [0 .. x])
А можно делать что-нибудь такое:
flatmapping (\x -> Set.insert a (Set.singleton b))
Ведь Set тоже Foldable.

(no subject)

From: [identity profile] voidex.livejournal.com - Date: 2014-09-22 10:18 am (UTC) - Expand

(no subject)

From: [identity profile] Колмогорова Простота - Date: 2014-09-22 10:23 am (UTC) - Expand

(no subject)

From: [identity profile] Колмогорова Простота - Date: 2014-09-22 10:28 am (UTC) - Expand

Date: 2014-09-22 09:26 am (UTC)
From: [identity profile] thedeemon.livejournal.com
Потерялся предыдущий коммент от rgtbctltpx :

---
Пока что как следует не разобрался с темой, но вроде бы, грамотно
реализованные на хаскеле трансдюсеры иногда всё-таки могут иметь
некоторый смысл. Например, внутренние промежуточные шаги вычисления могут
запускаться с любыми подходящими структурами данных и вместо списка там
можно вставить нечто более-эффективное-в-таком-то-конкретном-случае.

Интересные ссылки:

http://conscientiousprogrammer.com/blog/2014/08/07/understanding-cloure-transducers-through-types/
(см. "the fact that munge actually internally uses a list" - example2)

http://www.reddit.com/r/haskell/comments/2cv6l4/clojures_transducers_are_perverse_lenses/cjjiasy
---

Задний ум хаскелиста

Date: 2014-09-22 09:00 am (UTC)
From: [identity profile] livejournal.livejournal.com
Пользователь [livejournal.com profile] si14 сослался на вашу запись в своей записи «Задний ум хаскелиста (http://si14.livejournal.com/58177.html)» в контексте: [...] По мотивам http://thedeemon.livejournal.com/87320.html [...]

Date: 2014-09-22 01:32 pm (UTC)
From: [identity profile] valentin budaev (from livejournal.com)
> то все эти трансменьшители сводятся к такому типу:
> transducer: [a] -> [b]

Почему именно transducer: [a] -> [b]? Почему не (Nat -> a) -> (Nat -> b), например?

Date: 2014-09-23 04:39 am (UTC)
From: [identity profile] thedeemon.livejournal.com
Хотя бы потому что (Nat -> b) не кодирует пустую или даже просто конечную последовательность.

Date: 2014-09-23 09:38 am (UTC)
From: [identity profile] valentin budaev (from livejournal.com)
Да, я потом заметил ошибку, но смысла поста это не меняет (можно поставить любой изоморфный списку тип, тысячи их). Все программирование состоит исключительно в том, чтобы понять какой из изоморфных объектов выбрать. Если вы все программирование выкинули (т.к. все способы написания одной и той же программы все равно же эквивалентны и неразличимы с теоретико-категорной точки зрения), то что содержательного в принципе остается? Это же утверждение из разряда "все тьюринг-полные языки эквивалентны, по-этому давайте будет писать на брейнфаке".

(no subject)

From: [identity profile] lomeo.livejournal.com - Date: 2014-09-24 08:11 am (UTC) - Expand

(no subject)

From: [identity profile] valentin budaev - Date: 2014-09-24 10:32 am (UTC) - Expand

(no subject)

From: [identity profile] thedeemon.livejournal.com - Date: 2014-09-26 05:00 am (UTC) - Expand

(no subject)

From: [identity profile] valentin budaev - Date: 2014-09-28 01:50 pm (UTC) - Expand

(no subject)

From: [identity profile] thedeemon.livejournal.com - Date: 2014-09-29 05:14 am (UTC) - Expand

(no subject)

From: [identity profile] valentin budaev - Date: 2014-09-29 07:08 am (UTC) - Expand

(no subject)

From: [identity profile] thedeemon.livejournal.com - Date: 2014-09-29 08:15 am (UTC) - Expand

(no subject)

From: [identity profile] valentin budaev - Date: 2014-09-29 10:32 am (UTC) - Expand

(no subject)

From: [identity profile] thedeemon.livejournal.com - Date: 2014-09-29 10:45 am (UTC) - Expand

(no subject)

From: [identity profile] valentin budaev - Date: 2014-09-29 11:15 am (UTC) - Expand

(no subject)

From: [identity profile] thedeemon.livejournal.com - Date: 2014-09-29 12:14 pm (UTC) - Expand

(no subject)

From: [identity profile] valentin budaev - Date: 2014-09-29 12:40 pm (UTC) - Expand

(no subject)

From: [identity profile] valentin budaev - Date: 2014-09-29 01:18 pm (UTC) - Expand

(no subject)

From: [identity profile] thedeemon.livejournal.com - Date: 2014-09-29 02:38 pm (UTC) - Expand

(no subject)

From: [identity profile] valentin budaev - Date: 2014-09-29 03:16 pm (UTC) - Expand

(no subject)

From: [identity profile] thedeemon.livejournal.com - Date: 2014-09-30 06:30 am (UTC) - Expand

(no subject)

From: [identity profile] valentin budaev - Date: 2014-09-30 08:48 am (UTC) - Expand

(no subject)

From: [identity profile] thedeemon.livejournal.com - Date: 2014-09-30 09:30 am (UTC) - Expand

(no subject)

From: [identity profile] valentin budaev - Date: 2014-09-30 10:17 am (UTC) - Expand

(no subject)

From: [identity profile] voidex.livejournal.com - Date: 2015-02-03 07:50 am (UTC) - Expand

Date: 2014-09-23 08:23 am (UTC)
From: [identity profile] jakobz.livejournal.com
С [a] -> [b] - в целом понятно что для всех коллекций покатит. А с эвентами и прочими FRP что-то есть такое в хаскеле?

Date: 2014-09-23 09:05 am (UTC)
From: [identity profile] thedeemon.livejournal.com
Всякие итераты и кондуиты вроде как раз об этом. Но я в хаскельных библиотеках плохо ориентируюсь.

Date: 2014-09-26 09:15 pm (UTC)
From: [identity profile] testser.livejournal.com
I asked @richhickey and he said "a transducer is just a pre-fused Kleisli arrows in the list monad." #strangeloop (c) https://twitter.com/bodil/status/513031949586141184

Profile

thedeemon: (Default)
Dmitry Popov

February 2026

S M T W T F S
12 34567
891011121314
15161718192021
22232425262728

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Mar. 8th, 2026 11:02 am
Powered by Dreamwidth Studios