2012-05-19 6 views
3

Это домашнее задание, поэтому я не хочу ответа. Мне нужно только толчок в правильном направлении. Мне нужно сопоставить несколько функций в списке. Например:Перечислите список функций в список

(map-multi (list plus-one square) '(4 5 6)) => (25 36 49) 

Я могу иметь его карту первой функции к элементам списка, однако, я получаю очень потерял после этого. Кроме того, так как это вводный, я ограничен вводных функциями (const, append, car, cdr, member и т.д.)

(define (map-multi f l) 
    (cond 
     ((null? l) 
      l) 
     (else (cons ((car f) (car l)) 
      (map-multi f (cdr l)))))) 
+0

Это звучит, как вы хотите, чтобы применить состав функций в списке (если ваш пример есть 'квадрат 'а не' double', чтобы показать результат?). Вы можете найти ответы на этот вопрос полезным: http://stackoverflow.com/questions/9919732/a-function-builder-in-scheme/9920006#9920006. –

+0

Извините, да, он должен быть квадратным. – user1405177

+0

Сколько функций может быть передано в списке функций? всегда два? менее двух? более двух? –

ответ

2

Вы должны составить функции, которые вы получаете в параметре f. Для простоты предположим, что в списке есть только две функции - тогда вам нужно применить первую функцию к текущему элементу в списке чисел, а затем применить вторую функцию к результату этого. Если вы можете использовать compose процедура идти вперед с ним и изменить эту строку в коде:

((car f) (car l)) ; you're applying only the 1st function! what about the 2nd? 

... с этим один:

((compose (cadr f) (car f)) (car l))  ; now we're applying both functions 

Если вы не можете использовать compose, а затем заменить в той же строке с этим:

((cadr f) ((car f) (car l)))    ; now we're applying both functions 

Теперь, если проблема носит более общий характер, и вы должны отобразить список функций с более чем двумя элементов, а затем еще раз заменить ту же строку в коде с этим:

((compose-multi f) (car l)) 

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

(define (compose-multi flist)  ; procedure for composing a list of functions 
    (if (null? flist)    ; if the list is empty then 
     <???>      ; return the identity function 
     (<???> (compose-multi <???>) ; else compose the result of recursive call 
      <???>)))    ; with the current element in the list 

Обратите внимание, что функция идентификации требуется для обработки случая, когда в списке функций нет элементов; его очень просто определить, он просто возвращает то же значение, которое было передано как параметр.

Также следует знать, что compose-multi возвращает функцию, результат составления всех функций в списке - compose делает это для вас, но если вы не можете использовать его только помните, что это:

(compose x y) 

... эквивалентно следующему:

(lambda (n) (x (y n))) 
+1

Я бы предположил, что размер списка функций на самом деле не фиксирован в 2. Если это так, зачем использовать список вместо двух аргументов? – sepp2k

+0

@ sepp2k Ну, давайте попросим OP. И зачем использовать список? потому что это то, что учитель ОП попросил сделать домашнее задание :). Если вы правы, и в списке может быть более двух функций, проблема немного интереснее, но я сомневаюсь, что это было запрошено OP - это похоже на раннее назначение для некоторого курса программирования. –

+1

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

1

это может быть проще, чтобы написать это, как две функции. Один принимает список функций и один вход и применяет все функции в списке последовательно. Выход из одного приложения-функции будет входным для следующего; как только у вас закончились функции, которые вы выполнили.

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

+0

Мне нужно отправить письмо профессору, чтобы узнать, является ли это законным, или если оно должно быть реализовано как одна функция. То, как вы описали, было бы намного проще. – user1405177

+0

Вспомогательная функция также может быть внутренней функцией, использующей 'define' или' letrec', если вы охватили их в курсе. –

1

Чтобы согреться, начните с более простой проблемы. Затем обобщите решение.

Как вы могли бы написать эту функцию?

(define (map-single fs x) 
    ...) 

> (map-single (list double add1) 3) 
7 

, которая принимает список, fs, значений функции в качестве аргумента и числа, x, и вычисляется значение применения (композиции) функции в fs к x?

1

Вот альтернативный способ определения multi-map, который вместо композиции использует операцию, называемую fold. Поскольку вам разрешено использовать вводные функции, это не совсем ответ на ваше задание. Но это будет, если вы написать собственное определение fold (это не очень долго!)

(define (multi-map operations input) 
    (fold map input operations)) 

> (multi-map (list 1+ square) 
      '(4 10 8)) 
$2 = (25 121 81) 

> (multi-map (list 1+ square 1+) 
      '(4 10 8)) 
$3 = (26 122 82) 
Смежные вопросы