检测Scheme列表中的#<unspecified> </unspecified>

时间:2015-03-07 03:01:33

标签: scheme guile

我有一个返回值列表的函数。其中一些值可能是空列表本身,而有些则不是。但是,在每个列表的末尾,都存在#<unspecified>值。我知道当函数没有返回任何内容时会返回此值。

我想修剪此值以及其他空列表。

我的清单是这样的:
(() () MD- MC+. #<unspecified>)

我打算将过滤功能应用于此列表。 我将要应用的标准是null? 但是,当这应用于#<unspecified>值时,它会给我错误。如何从列表中删除#<unspecified>值?

应用过滤功能后该列表的输出应为: (MD- MC+)

我该怎么做?

4 个答案:

答案 0 :(得分:5)

您的列表不是正确的列表,而是虚线列表。所有高阶函数(如filterfoldmap,......都要求列表正确,因此无法使用此类列表。

我想知道你是否坚持使用这样的列表的原因可能是由于产生列表的过程中的错误。通常,如果你有一个递归程序..

(define (list-add1 lst)
  (if (pair? lst) 
      (cons (add1 (car lst)) (list-add1 (cdr lst)))))

现在,每个阴谋家都会立即看到这与:

相同
(define (list-add1 lst)
  (if (pair? lst) 
      (cons (add1 (car lst)) (list-add1 (cdr lst)))
      'UNDEFINED-IMPLEMENTATION-SPECIFIED-VALUE))

使用时,您会将正确的列表更改为虚线列表:

(list-add1 '(1 2 3)) ; ==> (2 3 4 . UNDEFINED-IMPLEMENTATION-SPECIFIED-VALUE)

解决方法是使用虚线列表来处理if的两个分支的过程。例如。

(define (list-add1 lst)
  (if (pair? lst) 
      (cons (add1 (car lst)) (list-add1 (cdr lst)))
      '()))

(list-add1 '(1 2 3)) ; ==> (2 3 4)

当然,如果不是这种情况,你可以通过将最终值保留在自己的缺点或删除它来将点线变换为正确:

(define (dotted->proper lst keep-value)
  (cond ((pair? lst) (cons (car lst) (dotted->proper (cdr lst) keep-value)))
        ((null? lst) '())
        (keep-value (cons lst '()))
        (else '())))

(dotted->proper '(1 2 . 3) #f) ; ==> (1 2)
(dotted->proper '(1 2 . 3) #t) ; ==> (1 2 3)

答案 1 :(得分:4)

在Guile中,您可以使用unspecified?来测试未指定的值。所以,您可以编写一个过滤函数,比如说null-or-unspecified?,如下所示:

(define (null-or-unspecified? x)
  (or (null? x) (unspecified? x)))

答案 2 :(得分:1)

返回任何值和返回未指定的值之间存在差异。您可以使用values不返回任何值:

> (values)
> 

如果RnRS标准表明返回值未指定,则意味着不同的实现可以自由返回它们喜欢的任何值。实际上,它意味着“不要使用返回的值”。您使用的实现已选择创建一个名为未指定值的具体值。它打印#<unspecified>。我建议您首先找出值来自哪里,而不是从列表中删除未指定的值。

答案 3 :(得分:0)

Guile和Chicken有特殊的谓词unspecified?。您可以按以下方式过滤列表:

(filter (compose not unspecified?) lst)

球拍具有void功能和void?谓词。

您也可以自己定义unspecified?

(define unspecified (begin))
(define (unspecified? v)
    (eq? unspecified v)
)