Обновить

Комментарии 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. А с устареванием в чистых функциях, наверное, действительно без хаков не получится

отсутствие побочных эффектов

референциальная прозрачность более широкое понятие

Референциальная прозрачность = можно заменить выражение его значением без изменения программы.

Включает:

  • Отсутствие побочных эффектов (не меняет внешний мир)

  • Детерминизм (один вход → один выход)

  • Независимость от контекста (не читает глобальные переменные, время)

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

Публикации