作为练习,我在Haskell中实现了一个'cons'操作,它从任意类型的两个值形成一对.实现所需的数据类型非常简单:
data Nil = Nil deriving (Eq)
data Pair a b = Cons a b deriving (Eq)
car (Cons x _) = x
cdr (Cons _ y) = y
caar = car . car
cdar = cdr . car
cadr = car . cdr
cddr = cdr . cdr
*Main> cddr (Cons 55 (Cons (1,2,3,4) "hello, world!"))
"hello, world!"
*Main>
Run Code Online (Sandbox Code Playgroud)
但是受到这个主题的启发,我想让结果对打印出来像Scheme列表一样 - 包括臭名昭着的"不正确的列表"(1 2 3 .4).我的实施(见下文)适用于Char的:
*Main> Cons 'a' (Cons 'b' (Cons 'c' Nil))
('a' 'b' 'c')
*Main> …
Run Code Online (Sandbox Code Playgroud) 我不明白为什么我们需要nil
[1]什么时候到cons
一个序列(所谓的正确列表)的项目.在我看来,我们可以通过单独使用所谓的不正确列表(cons
没有结束的-ed对nil
)来实现相同的目标.由于Lisps [2]已经提供了一个原始过程来区分a pair?
和一个原子(某些实现甚至提供atom?
),所以当在列表上定义一个过程时,例如length
,我可以只用虚线对做同样的事情,如下所示:
(define len
(lambda (l)
(cond ((pair? l) (+ 1 (len (cdr l))))
(else 1) ) ) )
Run Code Online (Sandbox Code Playgroud)
显而易见的是,与传统方法相比,我们可以将此程序应用于不正确的列表,'(1 . (2 . 3))
以获得预期的答案.3
(length '(1 2 3))
我想听听任何捍卫必要性的意见nil
.提前致谢.
[1]让我们忽略的争论焦点nil
/ NIL
,'()
和()
.
[2]这意味着Lisp语言系列.