假设我有一个相当简单的数据类型Person
,其中包含一些字段,以及一种保存Person
集合的类型。
data Person = Person { _name :: String, _age :: Int }
data ProgramState = PS { _dict :: IntMap Person }
makeLenses ''Person
makeLenses ''ProgramState
我想创建一个镜头,通过查找他们的密钥来访问个人。
person :: Int -> Lens' ProgramState Person
看起来,我进行这个操作的两个选项是使用at
或ix
索引到字典中。
-- Option 1, using 'at'
person :: Int -> Lens' ProgramState (Maybe Person)
person key = dict . at key
-- Option 2, using 'ix'
person :: Int -> Traversal' ProgramState Person
person key = dict . ix key
但是这两种选项都不能让我达到想要的效果,即使用
Lens'
访问 Person
而不是 Maybe Person
。选项1与其他镜头无法很好地组合,而选项2意味着我必须放弃我的获取器。我了解为什么要像这样编写
ix
和 at
。在字典中可能不存在该键,因此如果您想要一个既能够获取又能够设置的 Lens'
,它必须访问 Maybe a
。另一种选择是接受一个 Traversal'
,它可以访问0个或1个值,但这意味着您需要放弃获取器。但在我的情况下,我知道我想要的元素总是存在的,所以我不需要担心缺少键的情况。是否有一种方法可以编写我想要的内容,还是我应该重新思考我的程序结构?