如何编写Control.Lens.AT的实例

时间:2013-08-28 17:28:17

标签: haskell lenses lens

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

鉴于Struct k v lookupinsertupdatedelete,我必须做些什么才能使instance At (Struct k v)有效?

1 个答案:

答案 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

您仍需要定义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的参数顺序。