edytuj: Zazwyczaj eksperymentuję z ghci, aby zrozumieć nowy kod, więc dla takich jak ja stworzyłem School of Haskell post/page, który pochodzi z poniższych przykładów, ale są one edytowalne i można je uruchomić.
Pomyśl o tym, że te przykłady odpowiedzą na twoje pytania, ale z powodów praktycznych zamierzam zmodyfikować inny węzeł. Moja znajomość funkcji zamka błyskawicznego w lens jest raczej płytka. Trochę dłużej trwa czytanie i przyzwyczajenie się do typów w pakiecie lens w porównaniu do wielu innych pakietów, ale potem nie jest źle. Przed tym postem nie użyłem modułu zamka błyskawicznego ani modułu drzewa w pakiecie soczewek.
Drzewa nie są całkiem niezłe z show
, więc jeśli będę mieć czas, powrócę i dodaję całkiem niezłe wydruki, w przeciwnym razie prawdopodobnie kluczem będzie praca w repl z tymi przykładami, aby zobaczyć, co się dzieje.
Przedstawiamy
Jeśli chcę zobaczyć wartość pierwszego węzła, w zależności od tego tree lens package jest określany jako root, następnie możesz:
zipperTree & downward root & view focus
Modyfikowanie
Aby zmodyfikuj tę wartość i odtwórz drzewo (rezip the tree):
zipperTree & downward root & focus .~ 10 & rezip
Jeśli chcesz przesunąć gałęzie, musisz użyć downward branches
. Oto przykład, który modyfikuje katalog główny pierwszej gałęzi i rezipx drzewa:
zipperTree & downward branches
& fromWithin traverse
& downward root
& focus .~ 5
& rezip
Tutaj przechodzę w dół do listy oddziałów. Następnie używam fromWithin
użyć użyć traverse
do przechodzenia przez listę, jeśli to była krotka, mógłbym zamiast tego użyć both
.
zapisywanie i odtwarzanie ścieżek traversal
saveTape
i restoreTape
pozwolić, aby zapisać pozycję na zamek błyskawiczny, dzięki czemu może on zostać przywrócony ostatni.
Zapisz stanowisko:
tape = zipperTree & downward branches
& fromWithin traverse
& downward root
& saveTape
Następnie odtworzyć przechodzenie przez drzewa mogę:
t <- (restoreTape tape testTree)
Następnie można użyć t jako nowy zamek błyskawiczny i zmodyfikować go jako normalny:
t & focus .~ 15 & rezip
Taśma odtwarza kroki, które wykonałeś, dzięki czemu może pracować na innych drzewach, więc obserwacja zadziała z on tape jak zdefiniowano powyżej:
testTree2 = Node 1 [ Node 2 [] ]
t2 <- (restoreTape tape testTree2)
t2 & focus .~ 25 & rezip
Modyfikacja wielu lokalizacjach
Jeśli chcesz zmodyfikować wiele korzenie po prostu trzymać się na reziping zamek. Poniższa modyfikuje dwa korzenie testTree2:
zipper testTree2 & downward root
& focus .~ 11
& upward
& downward branches
& fromWithin traverse
& downward root
& focus .~ 111
& rezip
Dzięki za to. Jednak nie odnosi się to do mojej pracy domowej (tylko żartowanie). Nie próbuję modyfikować określonego węzła. Zamiast tego chcę przemierzyć całe drzewo i zapisać ścieżkę do pewnego węzła, który spełnia pewne warunki. W twoim przykładzie "modyfikującym" wiesz, że ścieżka to 'zipperTree & within (root.traverse.branches) >> = saveTape'. Zastanawiałem się, w jaki sposób mogę zdobyć ścieżkę, nie wiedząc o tym wcześniej (przechodząc). – Kai
Przydałby się konkretny przykład z większą ilością szczegółów. W przypadku powyższych prymitywów i rekurencji można odwiedzić każdy węzeł w drzewie, sprawdzić każdą wartość i zastosować do niej test. Gdy test się powiedzie, po prostu zwrócisz taśmę lub zapiszesz ją w monadzie stanu lub pisarza, jeśli jest to lepsze dla twojej aplikacji. – Davorak
Jest to bardzo pomocne! Jak korzystać z Data.Tree.Lens na moich własnych typach drzew? W szczególności, co jeśli jest to drzewo binarne zamiast drzewa różanego? – nont