Это не прямой ответ, и при этом он не обязательно на 100% точен, поскольку я не эксперт по функциональному языку. Но в любом случае, я поделюсь с вами своим опытом ...
Около года назад я был в такой же лодке, как и вы. Я сделал C ++ и C #, и все мои проекты всегда были очень тяжелыми для ООП. Я слышал о языках FP, прочитал некоторую информацию онлайн, пролистал книгу F #, но все еще не мог понять, как язык FP может заменить ООП или быть полезным в целом, так как большинство примеров, которые я видел, были слишком просты.
Для меня «прорыв» наступил, когда я решил изучать питон. Я скачал python, затем перешел на домашнюю страницу проекта euler и просто начал делать одну проблему за другой. Python не обязательно является языком FP, и вы, безусловно, можете создавать в нем классы, но по сравнению с C ++ / Java / C # он имеет гораздо больше конструкций FP, поэтому, когда я начал с ним играть, я принял сознательное решение не определить класс, если я не должен был.
Что мне показалось интересным в Python, так это то, насколько легко и естественно было брать функции и «сшивать» их для создания более сложных функций, и в конце концов ваша проблема все еще была решена путем вызова одной функции.
Вы указали, что при кодировании вы должны следовать принципу единой ответственности, и это абсолютно правильно. Но то, что функция отвечает за одну задачу, не означает, что она может выполнять только абсолютный минимум. В FP у вас все еще есть уровни абстракции. Таким образом, ваши высокоуровневые функции могут все еще выполнять «одну» вещь, но они могут делегировать функции более низкого уровня, чтобы реализовать более тонкие детали того, как эта «одна» вещь достигается.
Однако ключ к FP заключается в том, что у вас нет побочных эффектов. Пока вы рассматриваете приложение как простое преобразование данных с определенным набором входов и наборов выходов, вы можете написать код FP, который бы выполнил то, что вам нужно. Очевидно, что не каждое приложение хорошо вписывается в эту форму, но как только вы начнете это делать, вы удивитесь, сколько приложений подойдет. И здесь я думаю, что Python, F # или Scala сияют, потому что они дают вам конструкции FP, но когда вам нужно помнить ваше состояние и «вводить побочные эффекты», вы всегда можете прибегнуть к истинным и проверенным методам ООП.
С тех пор я написал целую кучу кода Python в качестве утилит и других вспомогательных сценариев для внутренней работы, и некоторые из них были значительно расширены, но, помня основные принципы SOLID, большая часть этого кода все еще получалась очень удобной в обслуживании и гибкой. Так же, как в ООП, ваш интерфейс является классом, и вы перемещаете классы по мере рефакторинга и / или добавления функциональности, в FP вы делаете то же самое с функциями.
На прошлой неделе я начал программировать на Java, и с тех пор почти ежедневно мне напоминают, что в ООП я должен реализовывать интерфейсы, объявляя классы с помощью методов, которые переопределяют функции, в некоторых случаях я могу добиться того же в Python, используя простое лямбда-выражение, например, 20-30 строк кода, которое я написал для сканирования каталога, в Python было бы 1-2 строками и без классов.
ФП сами по себе являются языками более высокого уровня. В Python (извините, мой единственный опыт работы с FP) я мог собрать понимание списка в другом понимании списка с добавленными лямбдами и прочим материалом, и все это было бы всего лишь 3-4 строками кода. В C ++ я мог бы абсолютно точно выполнить то же самое, но поскольку C ++ является более низким уровнем, мне пришлось бы писать гораздо больше кода, чем 3-4 строки, и по мере увеличения количества строк мое обучение SRP начиналось, и я начинал думать о том, как разделить код на более мелкие части (то есть, больше функций). Но в интересах удобства сопровождения и скрытия деталей реализации я бы поместил все эти функции в один класс и сделал их приватными. И вот, у вас это есть ... Я только что создал класс, тогда как в python я написал бы «return (.... lambda x: .. ....)»