Bazı işlemleri daha verimli hale getirmek için ağaç türünde yalnızca küçük bir ayar var. numaralı kağıt üzerinde odaklanan kağıtlar (ha ha) ağaçlarına sahiptir. kağıttan kod OCaml içinde ama Haskell çevirmek çok basittir: kısaca Özetlemek gerekirse
data Rose a = Leaf a | Rose [Rose a]
, fermuarlar fikri onun bağlamda bir veri yapısında pozisyon temsil etmektir. Bir gül ağacındaki bir düğümün bağlamı, düğümü ebeveynine ulaşmak için ağaca aldığınız yoldan ve düğümlerin kendisinin ulaşması için kardeşler listesinden aldığınız yoldan oluşur.
data Path a = Top | Node (Path a) [Rose a] [Rose a]
data Pos a = Pos { focus :: Rose a, path :: Path a }
Bu size right
ve down
yürüyerek gittiğiniz yerleri unutmadan ağaçtaki bir pozisyonda yakınlaştırmak ve sonra left
çekilirken ve up
uzaklaştırarak ağacı yeniden sağlar. up
tanımlamadaki
right, down, left, up :: Pos a -> Maybe (Pos a)
right (Pos _ Top) = Nothing
right (Pos _ (Node _ _ [])) = Nothing
right (Pos t (Node p ls (r:rs))) = Just $ Pos r (Node p (t:ls) rs)
down (Pos (Leaf _) _) = Nothing
down (Pos (Rose []) _) = Nothing
down (Pos (Rose (t:ts)) p) = Just $ Pos t (Node p [] ts)
left (Pos _ Top) = Nothing
left (Pos _ (Node _ [] _)) = Nothing
left (Pos t (Node p (l:ls) rs) = Just $ Pos l (Node p ls (t:rs))
up (Pos _ Top) = Nothing
up (Pos t (Node p l r)) = Just $ Pos (Rose (l ++ t:r)) p
bak. Şu anda odaklanmış olan düğüm ve kardeşleri t
, l
ve r
alır ve bunları tek bir çocuk listesinde toplar. Baktığın hangi düğümü unutuyor. Buna göre down
, mevcut odaklamanın en soldaki çocuğuna odaklanır. up
'a gidip, daha önce odaklanmış olan düğüme geri dönmeniz gerekiyorsa, O (n) işleminin olduğu yer olan listeye geri dönmek için right
adresine gidin.
Huet, ağaca 'yara izleri' bırakma düşüncesi, daha önce odaklanmış bir çocuğa dönmeyi daha uygun hale getirmekle ilgilidir. Rose
yapıcısını kendi odağıyla bir liste fermuarıyla çocukların listesini değiştirerek donatıyor.
data SRose a = -- for "scarred rose"
SLeaf a
| SEmpty -- replaces (Rose [])
| SRose [SRose a] (SRose a) [SRose a]
Path
ve Pos
türleri değişmeden kalır:
data SPath a = STop | SNode (SPath a) [SRose a] [SRose a]
data SPos a = SPos { sfocus :: Rose a, spath :: SPath a }
Şimdi, up
gitmek ve sonra geri down
, daha önce de aradıklarını unutmayın zaman.
up' (SPos _ STop) = Nothing
up' (SPos t (SNode p l r)) = Just $ SPos (SRose l t r) p
down' (SPos (SLeaf _) _) = Nothing
down' (SPos SEmpty _) = Nothing
down' (SPos (SRose l t r) p) = Just $ SPos t (SNode p l r)
Bu, ilgili söz konusu bazı bilgileri bulabilirsiniz: http://stackoverflow.com/questions/2990689/how-do-i-code-a-tree-of-objects-in-haskell-with- ebeveynlere-ve-çocuklara işaretçiler – Shersh