Pergunta

Estou aprendendo SICP agora e faço o ex2.23 Eu tenho o seguinte código:

(define (for-each proc items)
   (if (null? items)
       #t
       ((proc (car items))
        (for-each proc (cdr items)))))

Mas ao correr, causa erro: Procedimento Aplicação: Procedimento esperado, dado: #; Os argumentos foram: ()

Eu acho que sei o motivo: eu chamo a função for-EAça recursivamente, todo chamado for-Each queria retornar valor

Mas quando eu modifiquei o código:

(define (for-each proc items)
  (cond ((null? items) #t)
        (else (proc (car items)) (for-each proc (cdr items)))))

funciona bem. Eu não entendo, por quê? dentro cond, todo chamado para cada uma necessidade de retornar valor?

Eu usei o drscheme e escolha o idioma Sicp

Eu não sou um falante nativo de inglês, então se houver sth que não seja descrito claramente, por favor me diga

Foi útil?

Solução

Mas, ao executar, causa erro: Procedimento Aplicação: Esperado> Procedimento, fornecido: #; Os argumentos foram: ()

Eu acho que sei o motivo: eu chamo a função for-EACH RUSCURSIVAMENTE,> Todo chamado for-Each queria retornar valor

Não, é porque na cláusula alternativa de if você tem a combinação ((proc (car items)) (for-each proc (cdr items))). Você pretendia avaliar as duas combinações (proc (car items)) e (for-each proc (cdr items)) Sequencialmente, e para esse fim, você pensou que colocá -los em outro par de parênteses funcionaria. Mas, na verdade, o que você especificou é que o resultado de (proc (car items)) é um procedimento a ser aplicado ao argumento que é o valor de retorno de (for-each proc (cdr items)). Este não é o caso e você recebe um erro. O ponto principal é que os parênteses no LISP não são para agrupamento, mas têm um significado definitivo.

O problema é que if só pode ter uma única combinação nessa posição, enquanto você deseja ter duas em uma fileira. Por outro lado, cond não sofre tal restrição; você pode colocar o tempo uma sequência de combinações individuais na parte consequente de um cond Cláusula como seu coração deseja. Esse estado de coisas é simplesmente como o idioma é definido para funcionar.

Você também pode usar cond nessas situações, mas se você ainda quiser usar if Existem algumas opções para encher várias combinações em uma. Por exemplo. Você pode criar um procedimento de lambda cujo corpo são as duas combinações e imediatamente dispará -lo:

(define (for-each proc items)
   (if (null? items)
       #t
       ((lambda ()
          (proc (car items))
          (for-each proc (cdr items)) )) ))

Ou você pode usar begin que realmente deve ser usado para esse propósito:

(define (for-each proc items)
   (if (null? items)
       #t
       (begin
          (proc (car items))
          (for-each proc (cdr items)) ) ))
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top