Комментарии 8
Если вы говорите «монада», имея в виду Option, вы используете термин неправильно.
Если я говорю "рыба", имея в виду форель - я тоже использую термин неправильно? Я понимаю, что монады не ограничиваются одним Option, но ведь это же представитель монад, почему его вдруг нельзя называть общим термином?..
Судя по моим наблюдениям - их код не на 1% состоит из map, а процентов на 25.
Неужто и правда в каждой четвёртой строчке есть вызов map? Или там четверть кода - это тело функции, которая передаётся в map? Если второе - тогда подсчёт grep'ом тоже некорректен, потому что я более чем уверен, что тело функции зачастую длиннее однострочной лямбды.
монады используются в 14.4% строк
А переменные в том же JS - почти в 100% строк, а переменная в императивном языке - это ж, по сути, State-монада 🙃
Функциональное программирование - это про маленькие кирпичики
В первую очередь это про отсутствие побочных эффектов и функции как полноценные объекты языка.
Верно.
Я бы уточнил. Нет мутабельности, нет до и после. Нет IO. Как следствие, референциальная прозрачность. Скрытая мутация под капотом (мемоизация, оптимизации) допустима.
Без монад можно жить в ФП. Монады нужны, когда хочется явно и удобно связывать вычисления в “контексте” (Option/Result/Async/IO).
Скрытая мутация под капотом (мемоизация, оптимизации) допустима
Мемоизация в чистом ФП должна включать явную передачу кеша (можно упростить теми же монадами).
Можно и так ) Но тут кешируем настоящую функцию. Если задействовано I/O (пусть и с монадой) и закешированные значения могут устаревать, лениво "вычислить" всё сразу не получится.
Если задействовано IO, то можно просто сделать замыкание на переменную с кешем:
cache :: Ord a => (a -> IO b) -> IO (a -> IO b)
cache f = do
storageRef <- newIORef Map.empty
return $ \a -> do
storage <- readIORef storageRef
case Map.lookup a storage of
Just b -> return b
Nothing -> do
b <- f a
writeIORef storageRef (Map.insert a b storage)
return b
Правда, теперь сама функция кеширования тоже стала IO, но это редко доставляет какие-либо неудобства
P.S. А с устареванием в чистых функциях, наверное, действительно без хаков не получится
отсутствие побочных эффектов
референциальная прозрачность более широкое понятие
Референциальная прозрачность = можно заменить выражение его значением без изменения программы.
Включает:
Отсутствие побочных эффектов (не меняет внешний мир)
Детерминизм (один вход → один выход)
Независимость от контекста (не читает глобальные переменные, время)

Как на самом деле выглядит функциональное программирование?