Die at
-Methode sollte eine indizierte Linse für einen bestimmten Index zurückgeben, die als Eingabe Ihre Struktur erhält und sich wie folgt verhält:
- Beim Abrufen, wenn der Schlüssel nicht vorhanden ist, gib
Nothing
zurück, andernfalls gib den Wert des Schlüssels in der Struktur zurück.
- Beim Setzen, wenn der neue Wert
Nothing
ist, entferne den Schlüssel aus der Struktur, setze ihn andernfalls (oder erstelle ihn, wenn er noch nicht vorhanden ist) auf den Wert in dem Just
.
- Der Index ist einfach der dem
at
übergebene Schlüssel.
Dies führt zum folgenden Code für Ihre Anforderungen:
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
Ich verwende lens
um eine Linse zu konstruieren ilens
um eine indizierte Linse aus einem Getter und einem Setter zu konstruieren. Ich gehe auch davon aus, dass Ihre Funktionen die folgenden Typen haben:
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 sollte den Schlüssel überschreiben, wenn er bereits vorhanden ist
Sie müssen immer noch die Instanzen der Typfamilie IxValue
und Index
definieren:
type instance IxValue (Struct k v) = v -- Ein (Struct k v) enthält Werte vom Typ v
type instance Index (Struct k v) = k -- Ein (Struct k v) hat Schlüssel vom Typ k.
EDIT: Tatsächlich sollte at
eine indizierte Linse zurückgeben, nicht einfach nur eine Linse. Außerdem habe ich die Reihenfolge der Argumente an den Setter verwechselt.