Haskell 疤痕有什么用处?

Haskell 疤痕有什么用处?,haskell,zipper,Haskell,Zipper,在Huet撰写的题为“拉链”的论文中,他还提到疤痕是拉链的一种变体。与拉链相比,疤痕几乎是闻所未闻的。拉链在哈斯克尔社区非常有名。在报纸上和互联网上的任何地方,我能找到的关于他们的信息都很少 所以我不得不问,它们到底是毫无用处,还是有什么用处,但大多数人都不知道?这只是对树类型的一个小小调整,以提高某些操作的效率 本文主要研究玫瑰树(ha-ha),即节点具有任意数量子节点的树。论文中的代码是OCaml,但将其翻译为Haskell不需要太多调整: data Rose a = Leaf a | Ro

在Huet撰写的题为“拉链”的论文中,他还提到疤痕是拉链的一种变体。与拉链相比,疤痕几乎是闻所未闻的。拉链在哈斯克尔社区非常有名。在报纸上和互联网上的任何地方,我能找到的关于他们的信息都很少


所以我不得不问,它们到底是毫无用处,还是有什么用处,但大多数人都不知道?

这只是对树类型的一个小小调整,以提高某些操作的效率

本文主要研究玫瑰树(ha-ha),即节点具有任意数量子节点的树。论文中的代码是OCaml,但将其翻译为Haskell不需要太多调整:

data Rose a = Leaf a | Rose [Rose a]
简单回顾一下,zippers的思想是通过上下文表示数据结构中的位置。玫瑰树中节点的上下文包括沿树向下到达节点父节点的路径,以及沿同级列表到达节点本身的路径

data Path a = Top | Node (Path a) [Rose a] [Rose a]

data Pos a = Pos { focus :: Rose a, path :: Path a }
这使您可以通过向右行走
和向下行走
来放大树中的某个位置,而不会忘记您所处的位置,然后通过向左后退
和向上缩小
来重建树

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
查看
up
的定义。它将
t
l
r
(当前关注的节点及其兄弟节点)合并为一个子节点列表。它会忘记您正在查看的节点。相应地,
down
将您聚焦在当前焦点最左边的子对象上。如果需要向上移动
然后再向下移动到先前关注的节点,则必须沿列表向右移动
返回到您所在的位置,这是一个O(n)操作

Huet在树上留下“伤疤”的想法是为了让孩子更方便地回到以前专注的孩子身边。他为
Rose
构造函数配备了自己的焦点,用一个列表拉链代替了子列表

data SRose a =  -- for "scarred rose"
      SLeaf a
    | SEmpty  -- replaces (Rose [])
    | SRose [SRose a] (SRose a) [SRose a]
路径
Pos
类型保持不变:

data SPath a = STop | SNode (SPath a) [SRose a] [SRose a]
data SPos a = SPos { sfocus :: Rose a, spath :: SPath a }
现在,当您向上移动
然后向下移动
时,您不会忘记之前看到的内容

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)

你可以在这个相关的问题中找到一些信息:有趣。但伤疤不就是组合式拉链吗?因为现在您将玫瑰树中的列表替换为一个列表拉链。@TheredBox完全正确。