gpt4 book ai didi

haskell - 使用 `at` 和 `ix` 组合镜头

转载 作者:行者123 更新时间:2023-12-02 18:02:23 25 4
gpt4 key购买 nike

假设我有一些相当简单的数据类型 Person有几个字段和一个包含 Person 集合的类型s。

data Person = Person { _name :: String, _age  :: Int }

data ProgramState = PS { _dict :: IntMap Person }

makeLenses ''Person
makeLenses ''ProgramState

我想创建一个镜头,让我可以通过查找个人 key 来访问他们

person :: Int -> Lens' ProgramState Person

看来我执行此操作的两个选择是使用 atix索引到字典中

-- 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 意味着我必须放弃 setter/getter 。

我明白为什么 ixat都是这样写的。该 key 可能不存在于字典中,因此如果您想要 Lens'它同时启用 getter 和 setter,它必须访问 Maybe a 。另一种方法是接受 Traversal'它可以访问 0 或 1 值,但这意味着放弃 getter。但就我而言,我知道我想要的元素将始终存在,因此我不需要担心丢失键。

有没有办法写我想写的东西 - 或者我应该重新考虑我的程序的结构?

最佳答案

您可能希望将 atnon 同构一起使用。您可以用它指定一个默认的映射条目,以摆脱查找的也许

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

您可以查看更多示例in the docs.

关于haskell - 使用 `at` 和 `ix` 组合镜头,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20901710/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com