Lisp/Scheme中的自引用数据结构

sgi*_*ons 18 lisp scheme functional-programming graph data-structures

有没有办法在lisp或scheme中构建一个自引用数据结构(比如带有周期的图形)?我之前从未想过它,但是由于缺乏进行破坏性修改的方法,我可以找不到任何简单的方法来制作它.这只是函数式语言的一个重要缺陷,如果是这样,那么像haskell这样的懒函数语言呢?

Rai*_*wig 14

在Common Lisp中,您可以修改列表内容,数组内容,CLOS实例的插槽等.

Common Lisp还允许读写循环数据结构.使用

? (setf *print-circle* t)
T

; a list of two symbols: (foo bar)

? (defvar *ex1* (list 'foo 'bar))
*EX1*

; now let the first list element point to the list,
; Common Lisp prints the circular list

? (setf (first *ex1*) *ex1*)
#1=(#1# BAR)

; one can also read such a list

? '#1=(#1# BAR)
#1=(#1# BAR)

; What is the first element? The list itself

? (first '#1=(#1# BAR))
#1=(#1# BAR)
? 
Run Code Online (Sandbox Code Playgroud)

所谓的函数式编程语言不允许副作用.大多数Lisp方言并不纯粹.它们允许副作用,并允许修改数据结构.

有关详细信息,请参阅Lisp介绍书.


Ada*_*eld 9

在Scheme中,你可以使用set!,set-car!set-cdr!(以及以bang('!')结尾的任何其他结果,表示修改):

(let ((x '(1 2 3)))
  (set-car! x x)
  ; x is now the list (x 2 3), with the first element referring to itself
  )
Run Code Online (Sandbox Code Playgroud)

  • 请注意,改变不可变数据不是根据报告,结果是 *undefined*。通过将“(1 2 3)”替换为“(list 1 2 3)”,它将在报告中。 (2认同)

Dou*_*rie 9

Common Lisp支持修改数据结构setf.

您可以通过打结来在Haskell中构建循环数据结构.


hua*_*uan 5

  1. 您不需要“破坏性修改”来构建自引用数据结构;例如,在 Common Lisp 中,'#1=(#1#)是一个包含自身的 cons-cell。

  2. Scheme 和 Lisp 能够进行破坏性修改:您可以像这样构造上面的循环 cons: (let ((x (cons nil nil))) (rplaca x x) x)

你能告诉我们你在学习 Lisp/Scheme 时使用的材料吗?我正在为我们的黑色直升机编制目标清单;必须停止传播有关 Lisp 和 Scheme 的错误信息。