Pergunta

Este é o dever de casa, então não quero a resposta.Só preciso de um empurrão na direção certa.Sou obrigado a mapear várias funções em uma lista.Por exemplo:

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

Consigo fazer com que ele mapeie a primeira função para os elementos da lista, porém fico muito perdido depois disso.Além disso, por ser introdutório, estou limitado às funções introdutórias (const, append, car, cdr, member, etc.)

(define (map-multi f l)  
    (cond  
        ((null? l)  
            l)  
        (else (cons ((car f) (car l))  
            (map-multi f (cdr l))))))  
Foi útil?

Solução

Você precisa compor as funções que você recebe no f parâmetro.Para simplificar, digamos que existam apenas duas funções na lista - então você precisa aplicar a primeira função ao elemento atual na lista de números e depois aplicar a segunda função ao resultado disso.Se você puder usar o compose procedimento, vá em frente e altere esta linha em seu código:

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

...com este:

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

Se você não pode usar compose, e substitua a mesma linha por esta:

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

Agora, se o problema for mais geral e você precisar mapear uma lista de funções com mais de dois elementos e, mais uma vez, substitua a mesma linha em seu código por isto:

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

E implemente uma função auxiliar que compõe e retorna todas as funções da lista, por meio de chamadas sucessivas para compose.Este é deixado como um exercício para você, já que é um dever de casa - mas se você entender como o código acima funciona para apenas duas funções, deve ser fácil estender o resultado para uma lista de múltiplas funções:

(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

Observe que a função identidade é necessária para tratar o caso em que não há elementos na lista de funções;é muito simples de definir, apenas retorna o mesmo valor que foi passado como parâmetro.

Também esteja ciente de que compose-multi retorna um função, o resultado da composição de todas as funções da lista - compose faz isso para você, mas se você não tiver permissão para usá-lo, lembre-se do seguinte:

(compose x y)

...é equivalente a isto:

(lambda (n) (x (y n)))

Outras dicas

Pode ser mais fácil escrever isso como duas funções.Pega-se uma lista de funções e uma única entrada e aplica-se todas as funções da lista em série.A saída de uma aplicação de função será a entrada para a próxima;quando você ficar sem funções, estará pronto.

A outra função simplesmente mapeará esta função auxiliar em uma lista de entradas.

Aqui está uma maneira alternativa de definir multi-map que em vez de composição usa a operação chamada fold.Como você só pode usar funções introdutórias, esta não é realmente a resposta para sua tarefa.Mas será, se você escrever sua própria definição de fold (não é muito longo!)

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

Para se aquecer, comece com um problema mais simples.Em seguida, generalize a solução.

Como você escreveria esta função?

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

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

Isso requer uma lista, fs, de valores de função como argumento e um número, x, e calculou o valor da aplicação das (composição de) funções em fs para x?

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top