Для моих целей мне нужен контейнер, похожий на карту, с какими-то «свойствами». Не исключено, что мои объекты могут иметь разные свойства. Для доступа к свойствам я решил использовать Control.Lens, это очень интересно. Но я не могу найти подобный линзе способ для такой логики: при доступе к свойству, если оно не существует, вместо этого добавьте значение по умолчанию и верните новое. Но если он есть, просто используйте его.
Другими словами, prop_test должен возвращать True:
type PropertyMap = Map.Map Int String
data Properties = Properties { _propertyMap :: PropertyMap }
deriving (Eq)
makeLenses ''Properties
emptyProperties = Properties Map.empty
propertyLens pIndex = propertyMap . at pIndex . traverse
property1 = propertyLens 1
property2 = propertyLens 2
property3 = propertyLens 3
obj1Properties :: State Properties ()
obj1Properties = do
property1 .= "Property1 value"
property2 .= "Property2 value"
obj2Properties :: State Properties ()
obj2Properties = do
property1 .= "Property1 value"
property3 .= "Property3 value"
prop_test = op1 /= emptyProperties
where
op1 = execState obj1Properties emptyProperties
Но теперь op1 равен emptyProperties. В качестве значения по умолчанию я мог бы использовать Data.Default. Как мне с этим справиться? Или мне стоит использовать другой метод? Например, функция-оболочка в монаде State, которая распаковывает и проверяет наличие свойств для меня.
Также не могли бы вы дать ссылки на реальные примеры Control.Lens (или другого пакета линз)?