代码之家  ›  专栏  ›  技术社区  ›  nam

数据构造函数中的奇怪类型语法[重复]

  •  0
  • nam  · 技术社区  · 6 年前

    我找到了一些代码

    data Tree c a = Node String [Tree c a]
                  | NodeWithCleanup c [Tree c a]
                  | Leaf a
    

    我不明白为什么有必要加上 [Tree c a] .我不懂这个语法,你能给我解释一下吗?

    4 回复  |  直到 4 年前
        1
  •  5
  •   willeM_ Van Onsem    6 年前

    列表类型 []

    在Haskell列表中(概念上 链接列表 )是一种类型 [] 。列表只能包含 元素类型(因此列表不能包含 Int String s同时)。

    如果列表因此包含类型为的元素 a ,那么我们将其表示为 [a] 。例如 内景 s表示为 [Int]

    笔记 :此语法实际上是语法糖。如果你写信 [a] ,在你写的窗帘后面 [] a

    类型(带类型参数)

    在您引用的代码片段中,程序员定义了一个类型 Tree ,类型有两个类型参数 c (“清理”的类型)和 A. (叶子的类型)。这意味着 Tree c a 是一种 C 是清理类型和 A. 是叶类型。

    如果我们因此想要构建这样一个列表 s、 我们写作 [] (Tree c a) ,或更方便 [Tree c a]

    数据构造函数(带参数)

    程序员定义了三个 数据构造函数 。数据构造函数可以看作是附加到对象的标签,它们将“参数”绑定在一起。数据构造函数的参数数量可能不同,类型也可能不同。

    在代码片段中有三个数据构造函数:

    1. Node 采用两个参数的数据构造函数: 一串 以及 树c a s(其子公司);
    2. NodeWithCleanup 再次具有两个参数的dataconstructor:a C (清理)和 树c a s(其子公司);和
    3. Leaf 具有单个参数的数据构造函数:它存储的数据(类型 A. )。
        2
  •  3
  •   leftaroundabout    6 年前

    与Haskell中的大多数语法一样 [] 根本不是什么特别的语法 -of .构造函数声明只列出要包含的类型。如果您添加记录标签,它可能会变得更清晰:(我将在这里diregard清理部分)

    data Tree a
       = Node { nodeCaption :: String
              , subtrees :: [Tree c a] }
       | Leaf { leafContent :: a }
    

    这基本上类似于两个Python类:

    class TreeNode:
      def __init__(self, caption, subs):
          self.nodeCaption = caption
          self.subtrees = subs
    class TreeLeaf:
      def __init__(self, content):
          self.leafContent = content
    

    。。。拟建造如下

    TreeNode("foo", [TreeNode("bar1", TreeLeaf(1)), TreeNode("bar2", TreeLeaf(2))])
    

    在Haskell实现中,您只需编写

    Node "foo" [Node "bar1" (Leaf 1), Node "bar2" (Leaf2)]
    

    为此。


    -of 方括号 从某种意义上说,它们是为列表保留的特殊语法,但无论您是在函数的类型签名中还是在数据声明中编写它们,都是以相同的方式执行的。

        3
  •  2
  •   chi    6 年前

    定义值构造函数时 K ,表示法 K T1 T2 .. Tn 表示 K 构造函数 n 值,第一个为类型 T1 等等

    在里面 Node String [Tree c a] ,我们可以看到 Node 接受两个参数。第一个是字符串( String ).第二个是树的列表( [Tree c a] )因此,一个节点同时包含一个字符串和一系列子树。

    相反 NodeWithCleanup c [Tree c a] 表示具有清理功能的节点包含类型为的值 c 和一系列子树。

    Leaf a 表示叶包含类型为的单个值 a

        4
  •  0
  •   chepner    6 年前

    这不是语法问题;这是一个语义问题。A. Leaf 值仅包装类型的值 a .其他两个构造函数将 Tree 值,使其成为递归数据结构。A. Tree c a 是叶节点(例如。 Leaf 3 )或具有任意数量子树作为子树的内部节点(例如。 Node "foo" [Leaf 1, Leaf 3, (Node "bar" []] )。