假设我有一些相当简单的数据类型Person
,其中包含几个字段,以及一个包含Person
s 集合的类型。
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
但是这些选项都不能让我做我想做的事,那就是让 aLens'
访问 aPerson
而不是 a Maybe Person
。选项 1 不能与其他镜头很好地组合,选项 2 意味着我必须放弃我的吸气剂。
我理解为什么 ix
并且at
是这样写的。字典中可能不存在密钥,因此如果您想要一个Lens'
同时启用 getter 和 setter 的 a,它必须访问 a Maybe a
。另一种方法是接受 a Traversal'
,它可以访问 0 或 1 值,但这意味着放弃你的吸气剂。但就我而言,我知道我想要的元素将始终存在,所以我不需要担心丢失键。
有没有办法写出我想写的东西——或者我应该重新考虑我的程序结构?