Рекурсивные типы. Часть 6. Пересвёртка на практике

В этот раз мы разберём, как пересвёртка рекурсивных структур данных помогает в решении задач динамического программирования.

От Lisp до Haskell

В этот раз мы разберём, как пересвёртка рекурсивных структур данных помогает в решении задач динамического программирования.

Пятый пост Скотта Влащина посвящён конечным автоматам (они же машины состояний или даже стейт-машины). Функциональные языки хорошо подходят для реализации конечных автоматов, а конечные автоматы хорошо подходят для реализации бизнес-логики.
Попробуем?

Четвёртый пост из серии Скотта Влащина посвящена предметной области. Как с помощью типов описывать бизнес-правила? Как типы позволяют углубить понимание предметной области?
Узнаем прямо сейчас.

Привет, Хабр! Меня зовут Артём Корсаков. Я пишу на Scala и руковожу группой разработчиков в компании «Криптонит», а также веду Scalabook — русскоязычную базу знаний по Scala и функциональному программированию. В этой статье расскажу про обработку ошибок в библиотеке http4s на Scala 3. Мы разберём, как настроить декодирование запросов так, чтобы клиент получал не просто код “500” или “422” с общим сообщением, а сразу видел развёрнутый список всех проблем в запросе. Например, что логин уже занят, пароль содержит недопустимые символы, а капча не введена.
Пожалуй, самая раздражающая ошибка — это получение кода “500” в ответ на запрос, который ты десять раз перепроверил, сверился с документацией и уверен на все 100%, что запрос рабочий. Даже на 110%!
В такие моменты раздражённо думаешь: “Что же этому серверу надо? Я же чётко сформулировал запрос!
Ответить на этот вопрос порой сложно. Например, я хочу зарегистрироваться на сайте, ввожу логин/пароль и получаю сообщение "Internal Server Error". Первое желание – тут же покинуть сайт и поискать более дружелюбный.
Давайте подумаем, как можно сделать сообщение об ошибке более информативным. Для этого будем использовать Scala 3, уточняющие типы и http4s.
Представим, что мы создаём API сервиса авторизации, который (помимо прочего) должен регистрировать новых пользователей.
Для начала определим структуру данных для создания нового пользователя.

Новая глава из цикла Скотта Влащина. Обсуждаем, как сделать код надёжным с помощью развитых типов из F#.

Продолжаем перевод цикла статей Скотта Влащина, посвящённого проектированию программ в языках с развитой системой типов. В этой главе поговорим о том, как размеченные объединения помогают писать безопасный код.

Реализация ключевых конструкций лямбда‑исчисления на Python и объяснение их работы. Подойдёт даже тем, кто не очень знаком с Python.
Если хотите понять, как из одних лишь функций строятся булевы, списки и числа и, быть может, попробовать дойти до реализации некоторых алгоритмов самостоятельно — добро пожаловать под кат.
Я давно вынашивал желание написать эту статью. И, наверное, мне бы стоило потратить некоторое время на то, чтобы написать её чуть более структурно и продуманно, но, пожалуй, я её в таком случае вообще не напишу, так что - статья будет ad hock, прям from the top of my mind.
Начнём с того, что в обсуждениях объектного программирования бытуют несколько популярных мнений
Мотивацией для написания этого поста стали два года собеседований JS/TS-инженеров. Я интересуюсь языками и функциональным программированием, поэтому всегда «разбавлял» технические вопросы разговором о парадигмах. И заметил любопытную асимметрию.
Об ООП кандидаты рассуждали уверенно — но в основном на концептуальном уровне, не вдаваясь в то, как именно ООП реализовано в JavaScript. С FP картина была другой: уверенности меньше, зато критика — конкретная и повторяющаяся: «иммутабельность дорогая по памяти», «рекурсия небезопасна из-за стека». Что характерно — эти аргументы почти всегда были сформулированы через опыт работы с JS, а не с Haskell, Clojure или Scala.
Это важная деталь. Любая парадигма существует на двух уровнях: концептуальном (идеальная модель) и имплементационном (как конкретный язык эту модель выражает). Судить о FP по JS — примерно то же самое, что судить об ООП по bash-скриптам с глобальными переменными.
Параллельно я регулярно слышал, что JS — функциональный язык. Аргументы варьировались от «там есть .map()» до рассуждений о чистых функциях и каррировании. Именно это и стало поводом для поста: я хочу объяснить, что я считаю функциональным языком — и почему JS таковым не является. Не перечислить отсутствующие фичи, а показать, почему их нет и что это значит в реальном рантайме.

В поиске способов построения монад мы уже рассматривали сопряжения и расширения функторов. Свойства обеих абстракций выражаются естественными преобразованиями, но ещё не был представлен универсальный метод их получения. В этот раз мы познакомимся с техникой, позволяющей решать такие задачи.
В предыдущих частях мы видели, что все манипуляции в категориях происходят между морфизмами и совокупностями морфизмов. Для теории типов это вообще очевидный факт — любые конструкции (типы) являются функциями, преимущественно высокого порядка. В контексте вычислений обе теории представляют собой различные точки зрения на этот процесс, и между ними есть немало общего. В частности, функторы являются в первую очередь функциями на морфизмах, из которого следует (нефункциональное в общем случае) сопоставление объектов. Поэтому ожидается, что должен существовать конструктивный вывод возможностей описанных ранее абстракций.
Давайте рассмотрим технику исчисления концов через призму теории типов с использованием языка программирования Scala.
Время от времени мне нужно выполнить примитивный сценарий в терминале, но каждый раз это заканчивается очередным гуглежом «bash iterate each file» или «bash file has string». А что если скрипты в терминале можно было бы писать прямо как поток декларативных мыслей?

TL;DR: Затем, что с ним код чище, читаемее и предсказуемее ;)
Старый объектно-ориентированный или императивный подход к программированию несёт в себе множество проблем, которые решает функциональное программирование. Даже в современной среде все до сих пор считают, что объектно-ориентированное программирование — правильное программирование, а функциональное — «для математиков и задротов», или вообще даже для варваров, которые даже не слышали об объектной и императивной «цивилизации».

Привет, Хабр!
Парсер‑комбинаторы и синтаксический анализ в целом — очень интересные темы. Однако материалов со сравнительно низким порогом входа маловато, а в существующих статьях на читателя сразу обрушивается поток терминов и формальностей.
Эту статью я позиционирую как введение в парсер‑комбинаторы «для чайников» (или «для самых маленьких» — как вам больше нравится). Цель: попытаться рассказать простым языком и с примерами так, чтобы Вы могли после прочтения написать свой парсер без какого‑либо предварительного опыта и знаний в области синтаксического анализа.
Приятного чтения!

Программирование прямо сейчас переживает сдвиг в подходе к работе.
Если раньше основной процесс выглядел как «сел и пишешь код руками», продумываешь архитектуру, разбираешься с документацией и часами ищешь ошибки, то теперь всё чаще сценарий другой: ты формулируешь задачу, а реализацию на себя берёт ИИ.
Это и называют вайбкодингом.
Ты не работаешь на уровне синтаксиса — ты работаешь на уровне идеи. Задаёшь направление, описываешь поведение, уточняешь детали, а модель превращает это в код и структуру проекта.
Но здесь важно не попасть в иллюзию. Это не автоматическая разработка и не кнопка «сделать всё». Это инструмент, который даёт ускорение, но только если ты контролируешь процесс и понимаешь, что происходит.

TypeScript прочно закрепился в роли основного языка для типизированной разработки на JavaScript. Его система типов предоставляет множество мощных инструментов: дженерики, условные типы, продвинутый вывод типов – всё это позволяет строить надёжные и масштабируемые приложения. Однако даже в таком гибком языке есть ограничения. Одно из них – отсутствие нативной поддержки типов высшего рода (Higher-Kinded Types, HKT). Эта концепция, хорошо знакомая разработчикам на Haskell или Scala, позволяет абстрагироваться не только от конкретного типа (например, string или number), но и от типа-конструктора (например, Array, Promise, Set). Несмотря на то, что запрос на добавление HKT в TypeScript остаётся открытым уже много лет (issue #1213), сообщество научилось эмулировать эту возможность с помощью существующих средств. В этой статье мы разберём, что такое HKT, зачем они нужны в реальных проектах, и как их можно реализовать в TypeScript уже сегодня.

У меня двадцать лет в IT. Большую часть этого времени я проектировал и эксплуатировал инфраструктуру на PostgreSQL. Сейчас работаю архитектором: Go, Python, Postgres, Redis, ClickHouse, мониторинг на десятки тысяч баз. До этого писал на Ruby, пробовал Rust. Классический бэкенд-инженер со всеми вытекающими привычками: императивный код, мутабельное состояние, постоянные if err != nil { return err }.
А потом я начал писать бэкенд на Gleam — молодом функциональном языке на BEAM (Erlang VM), который появился в стабильной версии только в 2024 году. Навык ещё в разработке, но бэкенд уже работает, и я не жалею. Путь был... познавательным.
Эта статья — не туториал и не рекламный буклет. Это честный рассказ о том, почему я выбрал Gleam, какие шишки набил, что мне понравилось настолько, что я не хочу возвращаться, и что до сих пор бесит.

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

Добро пожаловать в чистилище препроцессора — место, где здравый смысл уступает место макросам. Сегодня мы заставим C++ притвориться Haskell-ем и внедрим do-нотацию, за которую любой адепт «чистого языка» предаст нас анафеме.
Программисты на C++ делятся на два типа: те, кто боится препроцессора, и те, кто познал сие древнее чудо с сишных времён.
Сегодня мы перейдем черту. Функциональное программирование манит своими абстракциями, но когда дело доходит до цепочек вычислений в монадах, C++ встречает нас бесконечными лямбдами и вложенностью, от которой рябит в глазах. В Haskell эта проблема решена элегантным do-синтаксисом. А что, если я скажу, что мы можем получить то же самое в C++, используя лишь тёмную магию макросов, простые шаблоны и полное пренебрежение здравым смыслом?
Приготовьтесь: мы будем дорабатывать парсер и превращать ваш код в нечто, что заставит коллег вызвать экзорциста. Это история о том, как затащить чистую красоту монад в суровый мир C++.

Доброго здоровья!
Предполагается, что статья будет интересна тем, кто любит четкие контракты в своих проектах, строгость и чистоту в инкапсуляции, новые подходы в ООП. А также тем, кто уважает функциональное программирование.
Эти темы и затрагиваются в предлагаемом «Elvis-модификаторе доступа», реализованным через Roslyn Analyzer. Все исходники и nuget пакеты прилагаются.

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