Sherzod
Если это был сарказм, то можно и разъяснить
Не понял, зачем для таких обычных вещей такие сложные слова придумывать
Vladislav
Что в них сложного?
Cheese
придумай слова попроще
Дима
Потому что это абстракция для которой уже давным давно закончились какие-то приземлённые аналогии
Vladislav
Да вроде и слово несложное
Дима
Примерно в этот момент и придёт понимание почему именно так а не проще
Sherzod
придумай слова попроще
профунктор это бифунктор, контравариантный по первому параметру ^ всё сложно Из всего только "функтор" в голову лезет. Объект, который можно вызвать (функтор в спп)
Cheese
можно говорить «плюшечка» вместо «профунктор», но это не сделает его понятнее
Дима
Контрплюшечка
Sherzod
можно говорить «плюшечка» вместо «профунктор», но это не сделает его понятнее
конечно не сделает, потому что не отражает того что оно объясняет
Vasiliy
> Из всего только "функтор" в голову лезет. Объект, который можно вызвать (функтор в спп) объект, который можно вызвать - функция, зачем придумывать такие сложные слова?
Sherzod
Это не тот функтор
это не фпшный функтор, да.
Vladislav
@Epikur В качестве эксперимента могу объяснить, что такое функтор (не в C++, а у здоровых людей), что такое бифунктор, что такое ко/контравариантность, и как из этого вытекает определение профунктора. Но взамен ты предложишь объективно более подходящие термины, чтобы новичку сразу по названию стало ясно, о чем речь
Vladislav
А если не готов придумать, то зря только воду мутишь
Дима
Он готов потому что не представляет в чем проблема
Sherzod
Ну очевидно что он этого не сделает)
вы обо мне плохого мнения :C
Vladislav
Бэкграунд опиши свой. Haskell на каком уровне знаешь?
parket
Вообще, для начала нужно курить теоркат. Но, для написания кода, это не обязательно.
Vladislav
Какой язык знаешь?
Sherzod
книжку с солнышком пытался открыть
Sherzod
C#
Дима
вы обо мне плохого мнения :C
P = PN тоже не докажешь, увы
Sherzod
P = PN тоже не докажешь, увы
да, за меня это сделают другие, и вроде как уже сделали
Дима
))
Дима
Ясн
Alex
не, там нашли фейл
Sherzod
не, там нашли фейл
ну тогда ждем след тысячалетия
Дима
Скорее !=
=, в этом и фича, про что я говорю
Vladislav
Ок, C#. Я его плохо помню, но попробую что-нибудь сообразить. Представь себе всякие контейнеры — списки, деревья, массивы, и т.д — штуковины хранящие в себе элементы.
Vladislav
Добавь в кучу опциональные значения (по сути список из 0 или 1 элемента)
Vladislav
Между ними общего то, что в них лежат элементы, и для них можно придумать функцию map, которая будет принимать делегат и применять к каждому элементу
Дима
Скорее !=
Нельзя придумать "понятные" термины если в языке просто кончились слова для подобных абстракций так же как нельзя доказать что PN = P, я в этом плане
Aragaer
в доказательстве, что не равны, нашли фэйл. С другой стороны недавно проскочило, что задача про расстановку ферзей NP, но вроде как ее почти-почти решили, а это значит P=NP. Если я ничего не путаю
Vladislav
Ну да, и так сойдет.
parket
Не, forEach предполагает сайдэффект :(
Vladislav
Я ее запишу вот так: map : (a -> b, T a) -> T b, обозначая стрелочкой функцию, а заглавной T контейнер
Vladislav
На вход имеем преобразование элемента типа a в элемент типа b, на выход имеем новый контейнер (с новыми элементами)
Sherzod
это Select что ли? Потому как ForEach ничего не возвращяет
Vladislav
Оно сохраняет форму, т.е. если на вход дерево, то и на выход дерево
Evgeniy
да Select больше похож
Vladislav
если ты туда передашь делегат x => x, то получишь на выход исходную штуковину.
Evgeniy
Range(1, 10).Select(x => x * x);
Evgeniy
выглядит как map
Vladislav
Так вот, для этой операции есть два закона во-первых, если сделаешь map функцией x => x, то получишь исходную структуру во-вторых, если сделаешь map f, а потом map g, где f и g это функции, то это равносильно тому, что ты сделаешь map (x => f(g(x)))
Vladislav
логично?
Sherzod
нет
Sherzod
map (x => g(f(x))) так логично
Vladislav
ну да, да
Vladislav
Так вот, можно рассмотреть другие штуковины, кроме контейнеров, для которых возможно определить map
Vladislav
Например, можно сделать map одной функции на другую — это будет означать, что мы применяем их последовательно оба закона выполняются
Vladislav
"последовательно" в смысле, что результат одной передается в другую
Sherzod
каррирование? (слышал такое умное слово)
Vladislav
я записывал тип map вот так: map : (a -> b, T a) -> T b мы можем в качестве T взять Tree, List, Array, что-нибудь еще там. А можем взять сами функции map : (a -> b, x -> a) -> (x -> b) я подставил x -> в качестве T
Sherzod
как это выглядит? f.map(x => g)?
Vladislav
это выглядит как f.map(g)
Vladislav
и раскрывается в x => g (f x)
parket
хорошая статья "Monads are trees with grafting"
Sherzod
Стоп
Vladislav
В общем в этой концепции главное понять, что мы можем рассматривать выходные данные функции как вещь, к которой применяется map
Evgeniy
еще можно это представить в уме как дженерик функция которая оперирует над другими дженериками
Evgeniy
( там где T есть Tree, List, Array...)
Vladislav
Вот рассмотрим массив ["a", "b", "c", "d"]. В нем по индексу 0 находится "a", по индексу 1 находится "b", etc Сделали map (x => x + "!"), получили ["a!", "b!", "c!", "d!"] (если в C# через + конкатенация строк, я не помню)
Vladislav
А теперь рассмотрим функцию гипотетическую toHex, которая из инта дает строчку — 0 в 0x0, 10 в 0xA, etc
Sherzod
ок
Vladislav
Сделаю я по ней map (x => x + "!") и получу функцию, которая из инта дает строчку — 0 в 0x0!, 10 в 0xA!, etc
Vladislav
В этом плане мы можем рассматривать входные данные как индексы, а выходные как элементы
Vladislav
а функцию как бесконечную структуру
Sherzod
начальный массив [0, 10, ...]? toHex.map(x => x + "!") так?