This media is not supported in your browser
VIEW IN TELEGRAM
Дискуссия в чатах, где ≥ 3 человек
Настроение дня: занимаюсь ФП на языке со структурной типизацей.
Да, я пишу в стиле Tagless Final на TypeScript. Это пиздец. Это ад, треш и содомия, потому что в языке нет нормальной поддержки HKT. Глубочайшее уважение и вечный респект Giulio Canti, который с помощью библиотеки fp-ts делает из тайпскрипта более-менее человеческий язык, но все равно — я несколько страдаю.
Да, я пишу в стиле Tagless Final на TypeScript. Это пиздец. Это ад, треш и содомия, потому что в языке нет нормальной поддержки HKT. Глубочайшее уважение и вечный респект Giulio Canti, который с помощью библиотеки fp-ts делает из тайпскрипта более-менее человеческий язык, но все равно — я несколько страдаю.
GitHub
gcanti - Overview
mathematician and rock climber. gcanti has 79 repositories available. Follow their code on GitHub.
Решил для начала написать пример на фри монадах. Получилось как-то так. Всё-таки далеко тайпскрипту до выразительности хаскеля или хотя бы скалы, ой далеко.
Gist
Free monads example with fp-ts
Free monads example with fp-ts. GitHub Gist: instantly share code, notes, and snippets.
Закончил работу над примером Tagless Final на тайпскрипте. Получилось короче, чем на фри монадах, но более замутно из-за необходимости дважды прописывать интерфейсы — один раз для HKT, один раз для Type.
Gist
Tagless Final example with fp-ts
Tagless Final example with fp-ts. GitHub Gist: instantly share code, notes, and snippets.
Подытожу:
1. Главное различие фри монад и ТФ — фри монады описывают программу как данные (тип + инстанс типа), а ТФ — как выражение.
2. Оба этих стиля имеют право на жизнь в тайпскрипте, но это просто пиздец какой-то, а не программирование. Столько бойлерплейта ради сомнительного выхлопа.
3. В примерах это не отражено, но в ТФ проще комбинировать эффекты нескольких разных типов — например, если бы у меня был отдельный тип для работы с БД, отдельный для сетевых запросов, отдельный для логирования, я бы смог их комбинировать достаточно просто. Во фри монадах это сделать сложнее, зато в них проще «смотреть внутрь» значения и писать оптимизирующие интерпретаторы, чем в ТФ.
Я все равно буду продвигать оба этих стиля во фронтэнд как способ писать сложную, композируемую логику в безопасном и легко тестируемом стиле.
Такие дела.
1. Главное различие фри монад и ТФ — фри монады описывают программу как данные (тип + инстанс типа), а ТФ — как выражение.
2. Оба этих стиля имеют право на жизнь в тайпскрипте, но это просто пиздец какой-то, а не программирование. Столько бойлерплейта ради сомнительного выхлопа.
3. В примерах это не отражено, но в ТФ проще комбинировать эффекты нескольких разных типов — например, если бы у меня был отдельный тип для работы с БД, отдельный для сетевых запросов, отдельный для логирования, я бы смог их комбинировать достаточно просто. Во фри монадах это сделать сложнее, зато в них проще «смотреть внутрь» значения и писать оптимизирующие интерпретаторы, чем в ТФ.
Я все равно буду продвигать оба этих стиля во фронтэнд как способ писать сложную, композируемую логику в безопасном и легко тестируемом стиле.
Такие дела.
Тот же самый TF, но уже на Scala. Как говорится, nuff said.
Gist
Tagless Final example in Scala + Cats
Tagless Final example in Scala + Cats. GitHub Gist: instantly share code, notes, and snippets.
Джон ДеГуз повторяет те же мысли, к которым пришел вчера я:
https://mobile.twitter.com/jdegoes/status/1059056721643991040
https://mobile.twitter.com/jdegoes/status/1059056721643991040
Twitter
John Ⓐ De Goes
Final-tagless lets you build type-safe DSLs with type classes. Instances of the type class are interpreters for the DSL. Free Monad lets you build type-safe DSLs with a data structure. Functions on the data structure (called natural transformations) are interpreters…
Нашел просто охуительную вещь — имитацию
А вот использование:
Я в восхищении. Вот только типы теряются.
do-нотации из хачкеля для JS. Адаптировал для TS (лол). Оказалось, что придется пользоваться б-гомерзким any, так как вывод типов в генераторах пока не работает от слова «никак». Зацените, какая прелесть:const doM = <A>(gen: Lazy<IterableIterator<any>>): A => {
let g = gen();
const step = (value: any) => {
const result = g.next(value);
if (result.done) {
g = gen();
return result.value;
} else {
return result.value.chain(step);
}
};
return step(undefined);
};А вот использование:
const id = doM<number>(function *() {
const begin = yield identity.of(identity.of(41));
const add = yield begin.ap(identity.of((x: number) => x + 1));
return add;
});
expect(id).toEqual(42);Я в восхищении. Вот только типы теряются.
(вложенные
identity.of нужны только для теста, чтобы проверить, что chain таки вызывается нужное кол-во раз)https://habr.com/company/epam_systems/blog/429308/ - интервью со мной опубликовали на Хабре. Странные, смешанные чувства.
Хабр
Как я ушел из стартапа в большую компанию
Строить карьеру – не идти по лестнице, где с каждой новой ступенькой на тебя сваливается более важная должность. Расти – это, скорее, учиться новому, не бояться...