Data structures 数据结构差异化、直觉构建

Data structures 数据结构差异化、直觉构建,data-structures,haskell,algebraic-data-types,Data Structures,Haskell,Algebraic Data Types,根据数据结构的差异化工作 根据: 在微分学中,数据类型D(给出为D')的导数是具有单个“孔”的D结构类型,即不包含任何数据的可分辨位置。这惊人地满足了微积分微分的相同规则 这些规则是: 1 = 0 X′ = 1 (F + G)′ = F' + G′ (F • G)′ = F • G′ + F′ • G (F ◦ G)′ = (F′ ◦ G) • G′ 参考文献对我来说有点太复杂了,我没有直觉。 这在实践中意味着什么?一个具体的例子就太棒了。X中X的单孔上下文是什么?没有选择:它是(-

根据数据结构的差异化工作

根据:

在微分学中,数据类型D(给出为D')的导数是具有单个“孔”的D结构类型,即不包含任何数据的可分辨位置。这惊人地满足了微积分微分的相同规则

这些规则是:

 1 = 0
 X′ = 1
 (F + G)′ = F' + G′
 (F • G)′ = F • G′ + F′ • G
 (F ◦ G)′ = (F′ ◦ G) • G′
参考文献对我来说有点太复杂了,我没有直觉。
这在实践中意味着什么?一个具体的例子就太棒了。

X中X的单孔上下文是什么?没有选择:它是(-),可以用单位类型表示


X*X中X的单孔上下文是什么?它类似于(-,x2)或(x1,-),所以它可以用X+X(或者2*X,如果你愿意的话)来表示


X*X*X中X的单孔上下文是什么?它类似于(-,x2,x3)或(x1,-,x3)或(x1,x2,-),可以用X*X+X*X+X*X或(3*X^2,如果你愿意的话)来表示

更一般地说,带孔的F*G要么是带孔的F和完整的G,要么是带孔的F和完整的G

递归数据类型通常被定义为多项式的不动点

data Tree = Leaf | Node Tree Tree
实际上是说Tree=1+Tree*Tree。区分多项式会告诉您直接子树的上下文:叶中没有子树;在节点中,它是左侧的洞,右侧的树,或左侧的树,右侧的洞

data Tree' = NodeLeft () Tree | NodeRight Tree ()
这是一个多项式,它被区分并呈现为一个类型。因此,树中子树的上下文就是这些树步骤的列表

type TreeCtxt = [Tree']
type TreeZipper = (Tree, TreeCtxt)
例如,这里有一个函数(未测试代码),它在树中搜索通过给定测试子树的子树

search :: (Tree -> Bool) -> Tree -> [TreeZipper]
search p t = go (t, []) where
  go :: TreeZipper -> [TreeZipper]
  go z = here z ++ below z
  here :: TreeZipper -> [TreeZipper]
  here z@(t, _) | p t       = [z]
                | otherwise = []
  below (Leaf,     _)  = []
  below (Node l r, cs) = go (l, NodeLeft () r : cs) ++ go (r, NodeRight l () : cs)
“下面”的作用是生成与给定树相关的树的居民


区分数据类型是使“搜索”之类的程序通用化的好方法。

我的解释是,T的导数(拉链)是所有实例的类型,类似于T的“形状”,但正好有一个元素被“孔”替换

例如,列表是

List t = 1     []
       + t     [a]
       + t^2   [a,b]
       + t^3   [a,b,c]
       + t^4   [a,b,c,d]
       + ...   [a,b,c,d,...]
如果我们用一个孔(表示为
@
)替换这些“a”、“b”、“c”等中的任何一个,我们将得到

List' t = 0      empty list doesn't have hole
        + 1      [@]
        + 2*t    [@,b]     or [a,@]
        + 3*t^2  [@,b,c]   or [a,@,c]   or [a,b,@]
        + 4*t^3  [@,b,c,d] or [a,@,c,d] or [a,b,@,d] or [a,b,c,@]
        + ...
另一个例子是二叉树

data Tree t = TEmpty | TNode t (Tree t) (Tree t)
-- Tree t = 1 + t (Tree t)^2
因此,添加孔将生成以下类型:

{-

Tree' t = 0                    empty tree doesn't have hole
        + (Tree X)^2           the root is a hole, followed by 2 normal trees
        + t*(Tree' t)*(Tree t) the left tree has a hole, the right is normal
        + t*(Tree t)*(Tree' t) the left tree is normal, the right has a hole

          @    or      x     or     x    
         / \          / \          / \   
        a   b       @?   b        a   @?
       /\   /\     / \   /\      /\   /\ 
      c  d e  f   @? @? e  f    c  d @? @?
-}

data Tree' t = THit (Tree t) (Tree t)
             | TLeft t (Tree' t) (Tree t)
             | TRight t (Tree t) (Tree' t)
说明链式规则的第三个示例是玫瑰树(变量树):

导数表示
R't=List(rt)+t*List'(rt)*R't
,意思是

{-

R' t = List (R t)        the root is a hole
     + t                 we have a normal root node,
       * List' (R t)       and a list that has a hole,
       * R' t              and we put a holed rose tree at the list's hole

        x
        |
       [a,b,c,...,p,@?,r,...]
                    |
                   [@?,...]

-}

data Rose' t = RHit [Rose t] | RChild t (List' (Rose t)) (Rose' t)
请注意,
data List't=LHit[t]| LTail t(List't)

(这可能与传统类型不同,传统类型的拉链是“方向”列表,但它们是同构的。)


导数是记录如何对结构中的位置进行编码的系统方法,例如,我们可以使用:(未完全优化)进行搜索


实际上,这意味着您可以计算或构造数据类型的导数及◦ 是可以用来以更一般的方式描述数据类型的结构。孔可以用于拉链,通过这种方式,人们可以自动在数据结构中找到孔,这对泛型很有用。很清楚“和类型中的洞”或“积类型中的洞”应该是什么,所以你得到的正是数学家所说的微分。然后,你自动知道你可以做计算导数时所做的所有事情:链式规则、微分逆、偏导数、微分方程(指数?指数函子有没有用?),微分不动点方程的解(这就是你计算拉链类型的方法)@亚历山大:
e^X=1+X+X^2/2+X^3/3!+。如何划分类型?:)@KennyTM:
exp
被定义为
F'(X)=F(X)
(作为方程的“通用”解,无论是初始解还是终端解,就像列表是
L(X)=1+a L(X)
)的解一样)。我不知道满足它的函子(如果有的话),也不知道它们有什么用处。@Alexandre:如果存在这样的类型,它就不是“多项式类型”。(假设F(X)≠ 太棒了。非常直观的解释。我喜欢作者回答关于论文本身的问题。我将寻找在我的工作中应用数据类型派生的地方。
{-

R' t = List (R t)        the root is a hole
     + t                 we have a normal root node,
       * List' (R t)       and a list that has a hole,
       * R' t              and we put a holed rose tree at the list's hole

        x
        |
       [a,b,c,...,p,@?,r,...]
                    |
                   [@?,...]

-}

data Rose' t = RHit [Rose t] | RChild t (List' (Rose t)) (Rose' t)
locateL :: (t -> Bool) -> [t] -> Maybe (t, List' t)
locateL _ [] = Nothing
locateL f (x:xs) | f x       = Just (x, LHit xs)
                 | otherwise = do
                                  (el, ctx) <- locateL f xs
                                  return (el, LTail x ctx)

locateR :: (t -> Bool) -> Rose t -> Maybe (t, Rose' t)
locateR f (RNode a child)
      | f a       = Just (a, RHit child)
      | otherwise = do 
                      (whichChild, listCtx) <- locateL (isJust . locateR f) child
                      (el, ctx) <- locateR f whichChild
                      return (el, RChild a listCtx ctx)
updateL :: t -> List' t -> [t]
updateL x (LHit xs) = x:xs
updateL x (LTail a ctx) = a : updateL x ctx

updateR :: t -> Rose' t -> Rose t
updateR x (RHit child) = RNode x child
updateR x (RChild a listCtx ctx) = RNode a (updateL (updateR x ctx) listCtx)