Функция Scheme, применяющая функцию ко всем элементам списка, независимо от их глубины, при сохранении структуры списка - PullRequest
1 голос
/ 20 мая 2011

Эй, я работаю над домашним заданием о применении функции к каждому элементу в списке, углубляясь до необходимого уровня.

Я получаю сообщение об ошибке при вызове (забавно (машина л)), что

mcar: expects argument of type <mutable-pair>; given 5

и все же, когда я просто звоню (забавно), я получаю ошибку +: ожидает тип в качестве 1-го аргумента, учитывая: (5); другие аргументы были: 1

   (define (map-gen fun l)
    (if (null? fun) l 
        (if (null? l) '()
            (if (list? (car l))
                (append (map-gen fun (cdr l)) (map-gen fun (car l)))
                (append (map-gen fun (cdr l)) (fun (car l)))))))

Любая помощь приветствуется!

edit: это когда вызывается функция так:

(map-gen (lambda (x) (+ x 1))'(1 (2 (3 4))(((5)))))

Ответы [ 2 ]

2 голосов
/ 20 мая 2011

У вас есть несколько проблем:

  • вход fun, как ожидается, будет функцией, поэтому запрос (null? fun) не имеет большого смысла,

  • использование вами вложенных if s - это именно та вещь, которую cond решает гораздо более элегантно,

  • как сказал Кин, когда вы имеете дело с деконструкцией списков таким образом, cons гораздо более уместен,

  • запрос (list? (car l)) сломан - в этот момент вы знаете, что l не пустой список, но что, если это вообще не список?

Хороший способ подойти к этому - подумать о типе l входов, с которыми вам нужно иметь дело:

  • это может быть пустой список, и в этом случае ответ прост,

  • это может быть пара (лучше всего проверить это с pair?, хотя list? тоже будет работать, если вы не беспокоитесь о "неправильных списках"), в этом случае вам нужно что-то сделать с его car и его cdr и объединить результаты таким образом, чтобы соответствовать исходной структуре (это легко),

  • или это может быть что-то еще (и этот случай тоже прост).

Лучше всего начать с написания нескольких примеров того, как вы хотите, чтобы он работал, затем заполнить код для его реализации и, наконец, превратить примеры в контрольные примеры, чтобы убедиться, что ваше решение работает. Вы действительно должны увидеть HtDP для этого - «рецепт дизайна», о котором идет речь, делает решение таких проблем настолько простым, что решение практически напишет само. (Учитывая, что вы делаете это на каком-то курсе, неплохо было бы указать это вашему учителю.)

2 голосов
/ 20 мая 2011

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

(define (map-gen fun l)
   (if (null? l) '()
       (if (list? (car l))
           (cons (map-gen fun (car l)) (map-gen fun (cdr l)))
           (cons (fun (car l)) (map-gen fun (cdr l))))))

Кроме того, как говорит Илай в своем ответе, вам действительно следует смотреть на cond вместо вложенных ifs. Это намного элегантнее, делая ваш код более читабельным.

...