2015-03-07 2 views
2

У меня есть функция, которая возвращает список значений. Некоторые из этих значений могут быть пустыми списками, а некоторые - нет. Однако в конце каждого списка присутствует значение #<unspecified>. Я понимаю, что это значение возвращается, когда функция ничего не возвращает.Обнаружение # <unspecified> в списке схем

Я хочу обрезать это значение вместе с другими нулевыми списками.

Мой список выглядит так:
(()() MD- MC+. #<unspecified>)

Я намерен применить функцию фильтра к этому списку. Критерии, которые я буду применять, - null?.
Однако, когда это применяется к значению #<unspecified>, оно дает мне ложную информацию. Как удалить значение #<unspecified> из списка?

Вывод этого списка после применения функции фильтра должен быть: (MD- MC+)

Как это сделать?

+0

Является ли точка на самом деле часть символа или, возможно, список выглядит как '(()() MD- MC + # .)'? – Sylwester

+0

Это не часть символа. Как вы сказали –

ответ

5

Ваш список не является собственным списком, а пунктирная список. Все функции высшего порядка, как 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) 

Конечно, если тот не тот случай, вы можете преобразовать пунктирный к собственно либо сохранению конечного значения в своих собственных недостатках или уронить:

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

Хороший улов неверный список! –

+0

У меня есть процедура, которая создает список со мной. Я могу отредактировать вопрос, чтобы показать вам процедуру. Я проверил, обрабатывала ли процедура обе ветви 'if' и это делалось. Поэтому я до сих пор не знаю, где «неопределенное» значение влезает. Должен ли я редактировать вопрос? –

+0

Решил. Самое главное, если ветка была проблемой. –

4

В Guile вы можете использовать unspecified? для проверки неопределенного значения. Таким образом, вы можете написать функцию фильтра, скажем null-or-unspecified? следующим образом:

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

Я использовал эту функцию следующим образом: '(фильтр null-or-unspecified? Test)' 'test' - это имя моего списка. Это дает мне ошибку, говоря «неправильный аргумент типа в позиции 2 (()« MC- ». # )' –

+0

Я думаю, что этот список сам по себе дает ошибку функции фильтра. Потому что даже простой фильтр '(= x 1)' дает мне ошибку. Что вызывает проблему? –

+1

См. Ответ Сильвестра. Это полностью пятно, и вы должны его принять. –

1

Существует разница между не возвращая никаких значений и возвращает неопределенное значение. Вы можете использовать values не возвращать никаких значений:

> (values) 
> 

Если стандарт RnRS говорит, что возвращаемое значение не определено, то это означает, что различные реализации могут свободно возвращать любое значение, что им нравится. По умолчанию это означает: «Не используйте возвращаемое значение. Реализация, которую вы используете, выбрала конкретное значение с именем неуказанное значение. Оно напечатано #<unspecified>. Вместо удаления неуказанного значения из списка, я рекомендую вам выяснить где значение приходят из в первую очередь.

0

Коварство и Chicken имеют специальный предикат unspecified? для этого. Вы можете фильтровать список так:

(filter (compose not unspecified?) lst) 

Ракетка имеет void функцию и void? предикат.

Также вы можете определить unspecified? по себе:

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