在Scheme中定义新数据类型

时间:2010-12-14 21:26:23

标签: functional-programming scheme algebraic-data-types

我首先需要提一下,我对Scheme很新,因此,下面的问题可能没什么意义。

在学校,我们定义了代数数据类型,它通常有一个无效的构造函数和一些内部/外部的构造函数。

在这种特殊情况下,我有兴趣制作一个BTree二叉树类型(可能在未来的迭代中平衡),我想要像this这样的Haskell如何处理构造函数。我之前已经看过如何在Scheme here中实现树,但这是我想要的。

我不想只是围绕列表做一个包装器。我只想写一些类似的东西:

nil: -> BTree
node: BTree x T x BTree -> BTree

然后让知道我的意思:

flattenTree: BTree -> List

然后,我会将其定义为(假设leftrightkey已定义:

(define flattenTree
  (lambda (t)
    (node (flattenTree (left t))
          (key t)
          (flattenTree (right t)))))

此外,我欢迎有关正确缩进我的计划代码的建议......(并且请加以修改)

1 个答案:

答案 0 :(得分:12)

在Scheme中表示二叉树(以及大多数其他数据结构)的规范方法是using lists。 Scheme的一些实现提供了一种用于定义C数据结构样式的新数据类型的工具。在MzScheme(现在的Racket)中,新的二叉树数据类型可以定义为:

(define-struct btree (key left right))

环境将自动为新结构创建构造函数,访问器和更改器程序。

> (define tree (make-btree 1 null null))
> (btree-key tree)
=> 10
> (set-btree-key! tree 10)

在此基础结构之上,您可以定义操作btree的其他过程:

(define (btree-insert! t key)
  (if (< key (btree-key t))
      (if (null? (btree-left t))
          (set-btree-left! t (make-btree key null null))
          (btree-insert (btree-left t) key))
      (if (null? (btree-right t))
          (set-btree-right! t (make-btree key null null))
          (btree-insert (btree-right t) key))))

(define (btree-flatten t)
  (define (flatten t result)
    (if (not (null? t))
        (begin
          (append result (append (flatten (btree-left t) ()) 
                                 (list (btree-key t)))
                  (flatten (btree-right t) ())))
        t))
  (flatten t ()))

;; test

> (define tree (make-btree 10 null null))
> (btree-insert! tree 12)
> (btree-insert! tree 9)
> (btree-insert! tree 8)
> (btree-insert! tree 15)
> (btree-flatten tree)
=> (8 9 10 12 15)