2

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

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

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

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

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

我该怎么做呢?

4

4 回答 4

6

您的列表不是一个正确的列表,而是一个虚线列表。所有高阶函数,如filter, fold, map, ... 都要求列表正确,因此不能使用此类列表。

我想知道您被此类列表困住的原因是否是因为生成该列表的过程中存在错误。通常如果你有一个递归过程..

(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)

当然,如果不是这种情况,您可以通过将最终值保留在其自身的缺点中或删除它来将 dotted 转换为正确的:

(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)
于 2015-03-07T16:19:02.267 回答
4

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

(define (null-or-unspecified? x)
  (or (null? x) (unspecified? x)))
于 2015-03-07T07:16:54.413 回答
1

不返回值和返回未指定的值是有区别的。您可以使用values不返回任何值:

> (values)
> 

如果 RnRS 标准说返回值未指定,则意味着不同的实现可以自由地返回他们喜欢的任何值。实际上它的意思是“不要使用返回的值。你使用的实现选择了一个具体的值,命名为未指定的值。它被打印出来#<unspecified>。而不是从列表中删除未指定的值,我建议你弄清楚在哪里价值首先来自于。

于 2015-03-07T09:08:49.390 回答
0

Guile 和 Chicken 对此有特殊的谓词unspecified?。您可以像这样过滤您的列表:

(filter (compose not unspecified?) lst)

Racket 有void函数和void?谓词。

您也可以unspecified?自己定义:

(define unspecified (begin))
(define (unspecified? v)
    (eq? unspecified v)
)
于 2016-07-03T17:39:41.410 回答