3 Stimmen

Wie schreibt man eine Instanz von Control.Lens.AT?

Ich habe eine Datenstruktur, die als analog zu Data.Map verstanden werden kann, da sie Schlüssel eines bestimmten Typs mit Werten eines anderen Typs verknüpft. Ich möchte eine Instanz von Control.Lens.At für diesen Typ schreiben, aber es scheint mir nie zu gelingen, alle Anforderungen zu erfüllen.

Angenommen, wir haben Struct k v mit lookup, insert, update und delete, was muss ich tun, damit instance At (Struct k v) funktioniert?

6voto

bennofs Punkte 11873

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.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X