再帰を使う以外に書けない。

行っている内容はリストの要素を走査して木をつくるというもの

  • 減少したらそこで打ち切り
  • 要素の値が深さを決めるのではなく、現在の値との大小関係

実行結果

(list->tree '(1 1 1 1)) ; => (1 1 1 1)
(list->tree '(0 1 1 2 2 1 1 2 1 0)) ; => (0 (1 1 (2 2) 1 1 (2) 1) 0)
(list->tree '(0 1 2 3 4 5 1 0)) ; => (0 (1 (2 (3 (4 (5)))) 1) 0)
(list->tree '(1 2 1 2)) ; => (1 (2) 1 (2))
(list->tree '(1 3 5 3)) ; => (1 (3 (5) 3))
(list->tree '(1 0)) ; => (1)

code

(use util.match :only (match))

(define (list->tree L)
  (define (remove-subnodes e xs)
    (or (member e xs) '()))
  (let loop ((n (car L)) (L L))
    (match L
      [() '()]
      [(n* . L*) 
       (cond ((= n n*) (cons n (loop n L*)))
             ((< n n*) (cons (cons n* (loop n* L*))
                             (loop n (remove-subnodes n L*))))
             (else '()))])))

再帰を直接使う以外方法なさそう?fold系はcdrループじゃないので無理だし。unfoldは分岐のための比較を2度行わなければならないので無駄。
break,span使う意味あまりないし。