Size: a a a

Scala User Group

2020 July 23

λ

λoλzod in Scala User Group
При этом ничего из этого не противоречит ООП
источник

GP

Grigory Pomadchin in Scala User Group
λoλzod
ФП парадигма сильно отличается от процедурно-ООП подхода, и это так сразу наверное и не объяснить в двух словах. Но одна из попыток это сделать была бы такая:

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

Появляется понятие эффектов и ссылочной прозрачности. Мы учимся разделять чисто математические (детерминированные) выражения и выражения с задействованием внешних переменных (баз данных, файлов, случайных чисел).

Типы, наряду с функциями, получают бОльшую роль, также применяются не только для моделирования предметной области, но и для эффектов и ошибок, паттерн матчинга.

Нашей основной заботой становится написание композируемых, то есть хорошо стыкуемых элементов (типов, функций). Композиция.

В целом мы более строго подходим к написанию и проектированию кода.
тлдр композиция и енто сложно
источник

λ

λoλzod in Scala User Group
да) и еще я забыл про ленивость, ленивые вычисления ключевой момент в обращении с эффектами
источник

GP

Grigory Pomadchin in Scala User Group
ну это следствия уже того что у тебя программа это композиция функций
источник

GP

Grigory Pomadchin in Scala User Group
не ‘ленивы' ли функции по умолчанию? они ж не вычислятся пока ты их не применишь
источник

GD

Gleb Donets in Scala User Group
Danila Romanov
А как ты его понимаешь, собственно?
Монада - это примитив, позволяющий компоновать многозначный (кортежем, например, или Some/Either) результат последовательного вызова функции с сохранением всех результатов
источник

GD

Gleb Donets in Scala User Group
Без ограничения на количество вызовов
источник

λ

λoλzod in Scala User Group
Grigory Pomadchin
не ‘ленивы' ли функции по умолчанию? они ж не вычислятся пока ты их не применишь
ну да, мы можем "моделировать" ленивые вычисления функциями, либо free структурами, по сути композируя выражения оставляя редукцию на потом
источник

GP

Grigory Pomadchin in Scala User Group
λoλzod
ну да, мы можем "моделировать" ленивые вычисления функциями, либо free структурами, по сути композируя выражения оставляя редукцию на потом
именно
источник

GD

Gleb Donets in Scala User Group
Например, если тебе нужно применить функцию fn(a), A => Either[Throwable, B] к результату предыдущего ее вызова несколько раз с сохранением результата каждого применения, fn( fn( fn (a))), монада позволяет сохранить все результаты и ошибки, которые возвращались при каждом из этих вызовов
источник

GD

Gleb Donets in Scala User Group
Кстати, не я же первый так сделал, как этого обычно избегают? Применительно к Akka Actors
источник

λ

λoλzod in Scala User Group
Gleb Donets
Например, если тебе нужно применить функцию fn(a), A => Either[Throwable, B] к результату предыдущего ее вызова несколько раз с сохранением результата каждого применения, fn( fn( fn (a))), монада позволяет сохранить все результаты и ошибки, которые возвращались при каждом из этих вызовов
не совсем так, хоть это и можно сделать с монадой, но не это её определяет
источник

DR

Danila Romanov in Scala User Group
В моем понимании монада это способ управлять "потоком управления", а  конкретнее - гарантировать последовательное исполнение там, где это нужно программисту.
Кто-то на ютубе пояснял это классным примером.
У вас есть F[A] и A=>F[B], а флатМап возвращает F[B]
Откуда же он мог взяться в функции? только из A=>F[B]. Т.е. мы знаем что A=>F[B] точно выполнилась на момент завершения флетмапа.
А как могла выполниться A => F[B]: только при наличии готового объекта A, которые в нее можно кинуть инпутом. А откуда мог взяться объект А? Только из F[A]
Таким образом во флетмапе гарантируется последовательность
F[A] -> A=> F[B] -> F[B]
источник

GD

Gleb Donets in Scala User Group
λoλzod
не совсем так, хоть это и можно сделать с монадой, но не это её определяет
Да, это для чего ее применяют. А вот ее определение от меня слегка ускользает, точнее, я на память его не помню
источник

λ

λoλzod in Scala User Group
грубо монада это такая структура, состоящая из тройки

типа монады: F
unit: A => F[A]
join: F[F[A]] => F[A]

где unit позволяет создать монаду, а join избавиться от вложенности

пример монады:

тип : List
unit : List(1)
join: List::flatten
источник

AD

Apache DOG™ in Scala User Group
Gleb Donets
Вдогонку: а в чем именно сложности писания на Скале (в функциональной манере) после ООП языков, что это так сложно?
Забыть о мутабилити
источник

AP

Andrey Patceev in Scala User Group
λoλzod
грубо монада это такая структура, состоящая из тройки

типа монады: F
unit: A => F[A]
join: F[F[A]] => F[A]

где unit позволяет создать монаду, а join избавиться от вложенности

пример монады:

тип : List
unit : List(1)
join: List::flatten
Законы забыл
источник

GD

Gleb Donets in Scala User Group
Apache DOG™
Забыть о мутабилити
Да и слава богу )))) Уже и в ООП-языках на код ревью просят исправить мутации там, где их видят. Всем больно
источник

GD

Gleb Donets in Scala User Group
Хотя, опять же, может, мне везет
источник

GD

Gleb Donets in Scala User Group
Спасибо за ответы )))
источник