Мне нравится библиотека Lens, и мне нравится, как она работает, но иногда она вводит так много проблем, что я сожалею, что когда-либо начал ее использовать. Давайте посмотрим на этот простой пример:Как избежать возвращаемого значения по умолчанию при доступе к несуществующему полю с объективами?
{-# LANGUAGE TemplateHaskell #-}
import Control.Lens
data Data = A { _x :: String, _y :: String }
| B { _x :: String }
makeLenses ''Data
main = do
let b = B "x"
print $ view y b
выводит:
""
А теперь представьте себе - у нас есть тип данных, и мы реорганизовать его - путем изменения некоторых имен. Вместо того, чтобы получать ошибку (во время выполнения, например, с обычными аксессуарами), что это имя больше не применяется к конкретному конструктору данных, объективы используют mempty
от Monoid
для создания объекта по умолчанию, поэтому мы получаем странные результаты вместо ошибки. Отладка чего-то подобного почти невозможна. Есть ли способ исправить это поведение? Я знаю, что есть некоторые специальные операторы, чтобы получить поведение, которое я хочу, но все «нормальные» функции от объективов просто ужасны. Должен ли я просто переопределять их с помощью моего настраиваемого модуля или есть ли более хороший метод?
В качестве побочного элемента: я хочу, чтобы читать и устанавливать аргументы с использованием синтаксиса объектива, но просто удалять поведение автоматического создания результата, когда поле отсутствует.
'Объективы предназначены главным образом для чистых видов продукции. Для типов сумм есть «Призма». Возможно, 'makeLenses' должен полностью отклонить ADT с несколькими конструкторами, но я полагаю, что иногда это полезно, что позволяет им. И довольно легко вспомнить, что вам нужно следить за использованием объективов с несколькими конструкторами, не так ли? – leftaroundabout
@leftaroundabout Хорошо, но могу ли я читать и писать значения при использовании 'makePrisms'? Я не читаю каждое значение как 'Maybe' (используя' preview').Я просто хочу читать и устанавливать значения, как позволяют обычные типы данных Haskell. Как это возможно? –
@Wojciech Типы записей с более чем одним конструктором, как правило, плохая идея, ИМХО. – danidiaz