Scheme - Function recursion error

天涯浪子 提交于 2019-12-11 20:01:09

问题


This function reads in a list and swaps values, but only when there's a key in the hash table that matches an element in the list. However, the list that is read in could contain other lists, and I want to check this recursively. I use if (list? elementInList) to determine whether I'm dealing with a list, so I can search that list for elements that may need to be swapped using a recursive call. I tried to do this but it's not handling the lists within the list correctly. What am I doing wrong?

(define (let-helper L)
    (map (lambda (x) (swap x (hash-ref *variable-table* x) L))
         (filter (lambda (x) 
                     (if (list? x)
                         (let-helper x) ;; recursion here
                         (hash-has-key? *variable-table* x)))
                 L)))

回答1:


I'd suggest just flattening the list so that you can continue to use map and filter like this:

(define (let-helper L)
  (map (lambda (x) (swap x (hash-ref *variable-table* x) L))
       (filter (lambda (x) (hash-has-key? *variable-table* x))
               (flatten L))))

Otherwise to get it to work would require writing it without map and filter like this:

(define (let-helper L)
  (let ((action (lambda (x) (swap x (hash-ref *variable-table* x) L)))
        (predicate (lambda (x) (hash-has-key? *variable-table* x))))

    (let loop ((a '()) (L L))
      (if (null? L)
          (reverse a)
          (if (list? (car L))
              (loop (cons (let-helper (car L)) a) (cdr L))
              (if (predicate (car L))
                  (loop (cons (action (car L)) a) (cdr L))
                  (loop a (cdr L))))))

Untested.


So the swap should only occur if the hash has the key but the returned list should still have the elements that weren't swapped? If so then not removing the element from the list of it isn't a key would fix that like this:

(define (let-helper L)
  (map (lambda (x) 
         (if (list? x) 
             (let-helper x) 
             (if (hash-has-key? *variable-table* x) 
                 (swap x (hash-ref *variable-table* x) L) 
                 x))))
       L)

Or

(define (let-helper L)
  (let ((action (lambda (x) (swap x (hash-ref *variable-table* x) L)))
        (predicate (lambda (x) (hash-has-key? *variable-table* x))))

    (let loop ((a '()) (L L))
      (if (null? L)
          (reverse a)
          (if (list? (car L))
              (loop (cons (let-helper (car L)) a) (cdr L))
              (if (predicate (car L))
                  (loop (cons (action (car L)) a) (cdr L))
                  (loop (cons (car L) a) (cdr L))))))


来源:https://stackoverflow.com/questions/33073053/scheme-function-recursion-error

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!