I have a data structure that can be understood as analogous to Data.Map
in that it maps keys of one type to values of another. I would like to write an instance of Control.Lens.At
for this type but I cannot ever seem to satisfy all the requirements.
Given Struct kv
with lookup
, insert
, update
, and delete
, what must I do to make instance At (Struct kv)
work?
The at
method should return an indexed lens for a given index gets as input your structure and behaves like this:
Nothing
, otherwise return the value at the key in the structure. Nothing
, remove the key from the structure, otherwise set it (or create it if it's not already there) to the value in the Just
. at
. This leads to the following code for your requirements:
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
I use
lens
to construct a lens
ilens
to construct an indexed lens from a getter and a setter. I also assume that your functions have the following types:
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
You still have to define the IxValue
and Index
type family instances:
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.
EDIT : Actually, at must return an indexed lens, not just a lens. I also confused the order of the arguments to the setter.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.