Подтвердить что ты не робот

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

Lenses, похоже, не имеют каких-либо недостатков, имея значительные преимущества перед стандартным Haskell: Есть ли какая-либо причина, по которой я не должен использовать линзы везде возможно? Есть ли соображения производительности? Кроме того, имеет ли шаблон Haskell существенные накладные расходы?

4b9b3361

Ответ 1

Линзы образуют альтернативу использованию прямых замыканий над конструкторами данных. Поэтому линзы имеют примерно одинаковые оговорки, как напрямую, так и непосредственно с помощью функций и конструкторов данных.

Некоторые из минусов из-за этого:

  • Каждый раз, когда вы изменяете объектив, вы потенциально можете создать много объектов (re). Например, если у вас есть эта структура данных:

    A { B { C { bla = "foo" } } }
    

    ... и объектив типа Lens A String, вы будете создавать новые A, B и C каждый раз, когда вы "модифицируете" этот объектив. Это ничего необычного в Haskell (создание множества объектов), но создание объекта скрыто за объективом, что затрудняет его поиск в качестве потенциального приемника.

  • Объектив также может создавать неэффективность из-за используемой "функции отображения". Например, если вы создаете объектив, который изменяет элемент 26 th в списке, это может привести к значительному замедлению из-за времени поиска.

И профи:

  • Объективы в сочетании с обычными записями можно использовать красиво с помощью монадов штата (см. data-lens-fd для примера), и это позволяет избежать в большинстве случаев, за счет большого обмена данными. См., Например, функцию focus и аналогичный шаблон использования withSomething функций в инфраструктуре Snap Web.
  • Объективы, очевидно, фактически не изменяют память на месте, поэтому они очень полезны, когда вам нужно рассуждать о состоянии в контексте concurrency. Поэтому линзы были бы очень полезны при работе с графиками различных типов.

Однако линзы не всегда изоморфны замыканиям над конструкторами данных. Вот некоторые из отличий (взяв data-lens в качестве реализации здесь):

  • Большинство реализаций объективов используют некоторую форму типа данных для хранения "accessor" и "mutator" в виде пары. Для data-lens это Store comonad. Это означает, что каждый раз, когда вы создаете объектив, из-за создаваемой структуры данных будут очень небольшие дополнительные накладные расходы.
  • Поскольку объективы зависят от значений через некоторое неизвестное отображение, может возникнуть трудность рассуждать о сборке мусора, и вы можете получить (логическую) утечку памяти, потому что вы забыли, что используете очень общий объектив, который зависит от большого количества Память. Возьмите, например, объектив, который обращается к элементу в каком-то большом векторе, который состоит из другого объектива, который таким образом скрывает первую линзу, что затрудняет просмотр того, что скомпонованная линза все еще зависит от большого объема памяти.

Код шаблона Haskell выполняется во время компиляции и не влияет на производительность среды выполнения.

Ответ 2

Я предполагаю пакет данных. Объективы для меня очень хорошо подходят для данных, подобных вещам (записи, кортежи, карты и т.д.). На самом деле они иногда даже лучше, чем обычный подход, вероятно, из-за лучшего обмена. С точки зрения производительности он производит примерно такую ​​же производительность, как и код, который вы бы написали вручную.

Однако существуют функционально-подобные вещи, для которых объективы могут иметь штраф. Например, я помню хотя бы один раз с помощью объектива, подобного этому:

result :: (Eq a) => a -> Lens (a -> b) b

В то время как запросы выполнялись очень быстро, я иногда переопределял некоторые значения результата функции, чтобы настроить ее на определенные сценарии, что эквивалентно включению тела функции в большой if. Разумеется, последствия производительности не связаны с самими линзами, но это что-то примечательное.