Как стать автором
Обновить

Комментарии 23

Мэта Тронтона.

Наверное, все-таки Торнтона?

Так все-же, и чем это отличается от всего, что вы читали? По мне — так почти все тоже самое, что и во многих других местах — кроме разве что использования F#, и некоторой его специфики. Вы сами заметили, что автор и до контейнеров дошел, и собственно, почему нет, если это очень часто осмысленная абстракция? Тем что тут «типы-контейнеры с „then-able“ функцией»? Так в тех самых статьях с картинками (я думаю мы одни и те же имеем в виду) тоже говорится, что контейнер не просто хранит нечто, а умеет применять функцию к своему содержимому.

Автора поправил, спасибо!

Я попытался объяснить свою мотивацию во вступлении, но, возможно, получилось не очень удачно.

Я не имел ввиду, что теория категорий или аналогии с коробочками - плохо, и такие статьи не нужны. Нужны, это просто другой взгляд на задачу и ее решение. Восприятие субъективно, мне всегда не хватало в дополнение к теории и аналогиям каких-то практических примеров. В данной статье мне нравится первая ее часть, где мы начинаем с разработки API оплаты, но код получается запутанный и мы постепенно придумываем, как избавится от этой запутанности. У нас получается паттерн. Я даже не хотел бы спорить, как этот паттерн надо называть и точно ли это Монада (наверно, напрасным было примечание про Promise), но ведь его надо как-то называть?

Вторая часть статьи, после "Поздравляю! Вы только что открыли Монаду", лично мне уже ничего для понимания не дает (возможно, как раз после тех постов с картинками), и я не хотел ее переводить. Но мне показалось, что нельзя перевести часть материала или добавлять отсебятину, так что перевел все как есть.

Это первая статья из цикла. Далее там начинаются всякие интересные эффекты, если у нас коробочка лежит в коробочке. Она подчеркнуто конкретна и довольно сильно разжевана. Поэтому предназначена, скорее для тех, кто только пытается понять, как и где ему монаду применить в реальной практике, чем для программистов на haskell.

Промис, работающий с синхронными функциями, - это полноценная монада, конечно :)

Я не вижу причинно-следственной связи между

Вместо этого мы можем поменять функцию с правой стороны от оператора, чтобы она могла принимать тип User option, а не просто User

и

Нам нужно что-то, что принимает функцию в качестве входных данных и преобразует ее в другую функцию.

у нас есть функция
User -> CreditCard option
а нужна нам
User option -> CreditCard option
Как нам из первой получить вторую? Ну можно взять функцию
(User -> CreditCard option) -> (User option -> CreditCard option)

Это функция высшего порядка, потому что оперирует другими функциями

А можно просто переписать первую и не городить бессмысленные конструкции

Переписать каким образом?

Чтобы эта функция принимала на вход аргупент option? Не, в целом подход с lift функцией прикольный, но обработка ошибок в lift отсутствует полностью, так что для промышленной рвзработки такой код неприемлем.

И как мне потом передать в такую функцию объект User?

Что касается обработки ошибок, в этом конкретном примере ошибки - это возможное отсутствие результата lookupUser или chargeCard, их обработкой мы и занимаемся.

И как мне потом передать в такую функцию объект User?

Если надо, перед передачей упаковать в Option

ошибки - это возможное отсутствие результата lookupUser или chargeCard, их обработкой мы и занимаемся

Не занимаемся. Чем этот действительно занимается - так это заметанием ошибок под ковёр.

Вот положим у меня цепочка вычислений из, ну скажем, 15 преобразований. Вернулся None. Надо понять почему. Как?

Если вам надо понять почему, то возвращайте Error, а не None.

Но зачем переписывать? getCrefitCard не нужно принимать на вход User option, потому что она не имеет какой-то дополнительной логики на случай обработки отсутствующего пользователя. Весь смысл функции lift как раз в том, чтобы разнести два ответственности: саму бизнес-логику и вспомогательную логику по проталкиванию None.

Видимо, я пропустил, потому что не знаю о чем речь)

Это нормально, разным людям понятны разные объяснения. Лично я склоняюсь к тому, что надо и Милевского (или Милевски?) почитать, и инфографику посмотреть и попытаться где-то применить в своей сиюминутной задаче.

Я считаю, что проблема всех туториалов про монады в том, что все объяснение монад ВСЕГДА заканчивается на Option, ценность которой, по моему мнению, около нуля, т.к. с помощью этой невероятно тупой монады не написать НИЧЕГО полезного. В реальном мире мы всегда хотим знать не только, что "что-то" пошло не так, но ещё и "где".

Для этого есть другая монада (Result), но с ней начинается другая беда - ошибок в программе может быть больше тысячи. Бросая даже один тип исключения мы всегда получим stacktrace с точным местом ошибки, а для Result придется иметь кучу возможных возвращаемых значений + сложности с обработкой этих ошибок. Кстати, в целом всегда показывают монады в стиле: "смотрите какой у нас классный код линейный", но никогда не показывают код обработки ошибок этого линейного кода.

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

Привет из декабря 2022го, теперь этот "туториал" не только про Option, упс претензия была преждевременной)

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

В функциональном мире функция нескольких аргументов переделывается в функцию одного аргумента элементарно.

Это я в курсе, но покажите мне код (с монадамм) после этого) Потому что это будет нечто невразумительное

Что ж, в функции getSecondArg что-то пошло не так. Надо это залогировать и послать сообщение юзверю. Как?

Так это не ответственность getSecondArg

Или вы хотите передавать в функцию StringToInt почту юзверя, чтобы он получил сообщение о том, что не удалось преобразовать строку в число?

если надо упасть на первой ошибке то использовать Except иначе для накопления ошибок Validate

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации