Chr*_*lor 6 haskell traversal haskell-lens
假设我有一些相当简单的数据类型Person,包含几个字段,以及一个包含Persons 集合的类型.
data Person = Person { _name :: String, _age :: Int }
data ProgramState = PS { _dict :: IntMap Person }
makeLenses ''Person
makeLenses ''ProgramState
Run Code Online (Sandbox Code Playgroud)
我想创建一个镜头,让我通过查找他们的密钥来访问个人
person :: Int -> Lens' ProgramState Person
Run Code Online (Sandbox Code Playgroud)
看来我这样做的两个选择是使用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
Run Code Online (Sandbox Code Playgroud)
但是这些选项都没有让我做我想做的事,Lens'也就是说有一个访问Person而不是a Maybe Person.选项1与其他镜头不能很好地搭配,选项2意味着我必须放弃我的吸气剂.
我理解为什么 ix并且at写得像这样.密钥可能不存在于dict中,因此如果你想要一个Lens'同时启用getter和setter 的密钥,它必须访问一个Maybe a.另一种方法是接受一个Traversal'允许访问0或1值的a,但这意味着放弃你的getter.但在我的情况下,我知道我想要的元素将永远存在,所以我不需要担心丢失键.
有没有办法写出我想写的东西 - 或者我应该重新考虑我的程序结构?
您可能希望at与non同构一起使用.您可以使用它指定默认映射条目以消除Maybe查找.
non :: Eq a => a -> Iso' (Maybe a) a
person key = dict . at key . non defaultEntry
-- can get and set just like plain lenses
someProgramState & dict . at someKey . non defaultEntry .~ somePerson
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
370 次 |
| 最近记录: |