0

我的作业有点麻烦。我必须创建一个请求列表列表和元素的过程,然后继续将元素添加到每个子列表中的第一个位置。我设法做到了,它看起来像这样:

(define (add-element lst elem)
   (foldr cons lst (list elem)))

(define (insert-first lst1 x)
  (cond
   [(empty? lst1) empty]
   [else (local [(define insert (add-element(first lst1) x))]
        (cons insert (insert-first (rest lst1) x)))]))

所以如果你要打字(insert-first '((a b) (c d)),你最终会得到(list (list 'x 'a 'b) (list 'x 'c 'd))

唯一的问题是我需要使用mapand对过程进行编码local。后一个我认为我完成了,但我无法为我的生活找出一种使用方法map

4

3 回答 3

5
(define (insert-first elt lst)
  (map (lambda (x)
         (cons elt x))
       lst))

然后

(insert-first 'x '((a b) (c d)))
=> '((x a b) (x c d))
于 2013-11-14T17:42:44.363 回答
0
(define (insert-first lst elem)
   (foldr (lambda (x y) (cons (cons elem x) y)) '() lst))

接近您的解决方案,但 map 比折叠更自然地适合该问题,因为您想对列表的每个元素执行某些操作。当您想通过连续将函数应用于该列表的元素来累积值时,请使用 fold。

于 2013-11-14T18:59:33.057 回答
0

foldr体现了一定的递归模式,

(foldr g init [a,b,c,...,z]) 
= (g a (foldr g init [b,c,...,z]))
....
= (g a (g b (g c ... (g z init) ...)))

如果我们在您的函数定义中手动扩展foldr调用,我们会得到add-element

  (add-element lst elem)
  = (foldr cons lst (list elem)) 
  = (cons elem (foldr cons lst '()))
  = (cons elem lst)

然后,查看您的insert-first函数,我们发现它太遵循foldr递归模式,

(insert-first lst1 x) 
= (foldr (lambda(a r)(cons (add-element a x) r)) empty lst1) 
= (foldr (lambda(a r)(cons (cons x a) r)) empty lst1)

但是(foldr (lambda(a r) (cons (g a) r)) empty lst) === (map g lst),因为将子术语与 结合起来cons就是建立一个列表,这就是这样map做的;所以我们得到

(insert-first lst1 x) = (map (lambda(a)(cons x a)) lst1)

所以我们可以写

(define (insert-first lst1 x)
  (local [(define (prepend-x a) (cons ... ...))]
    (map ... ...)))
于 2013-11-17T16:18:15.763 回答