我有一个可以理解为与Data.Map
类似的数据结构,因为它将一种类型的键映射到另一种类型的值。我想为这种类型编写Control.Lens.At
的实例,但我似乎无法满足所有要求。
鉴于Struct k v
lookup
,insert
,update
和delete
,我必须做些什么才能使instance At (Struct k v)
有效?
答案 0 :(得分:6)
at
方法应返回给定索引的索引镜头作为输入结构,行为如下:
Nothing
,否则返回结构中密钥的值。Nothing
,请从结构中删除密钥,否则将其设置(或创建它,如果它尚未存在)到Just
中的值。at
的关键。 这导致以下代码满足您的要求:
instance At (Struct k v) where
at key = ilens getter setter
where getter = (key, lookup key)
setter s Nothing = delete key s
setter s (Just newValue) = insert key newValue s
我使用 lens
来构建一个镜头ilens
来构建一个来自getter和setter的索引镜头。我还假设您的函数具有以下类型:
lookup :: k -> Struct k v -> Maybe v
delete :: k -> Struct k v -> Struct k v
insert :: k -> v -> Struct k v -> Struct k v
-- Insert should override the key when it's already there
您仍需要定义IxValue
和Index
类型系列实例:
type instance IxValue (Struct k v) = v -- A (Struct k v) contains values of type v
type instance Index (Struct k v) = k -- A (Struct k v) has keys of type k.
编辑:实际上,必须返回一个索引镜头,而不仅仅是一个镜头。我也混淆了setter的参数顺序。