出于我的目的,我需要一个带有某种“属性”的类似地图的容器。我的对象可能具有不同的属性。为了访问这些属性,我决定使用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 monad 中的一个包装函数,它为我解包并检查属性是否存在。
另外,您能否提供 Control.Lens(或其他镜头包)的真实示例的链接,好吗?