3

我有一个数据结构,可以理解为类似于Data.Map它将一种类型的键映射到另一种类型的值。我想Control.Lens.At为这种类型编写一个实例,但我似乎永远无法满足所有要求。

给定Struct k v, lookup,和insert,我必须做什么才能工作?updatedeleteinstance At (Struct k v)

4

1 回答 1

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来从一个吸气剂和一个设置器构造一个索引镜头。我还假设您的函数具有以下类型:

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

您仍然必须定义IxValueIndex类型族实例:

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 参数的顺序。

于 2013-08-28T18:16:19.950 回答