Есть две вещи, которые вызывают у вас горе в опубликованном коде: порядок аргументов в паре вызовов процедур и тип возврата одного вызова процедуры.
Процедура set-add
занимает set
в качестве первого аргумента, поэтому аргументы здесь необходимо поменять местами:
(set-add subset (set-first st))
Аналогично, set-map
принимает set
в качестве первого аргумента и процедуру в качестве второго:
(set-map ps
(lambda (subset) (set-add subset (set-first st))))
Теперь, несколько нелогично, set-map
возвращает list
, а не set
; Но set-union
ищет set
. Чтобы дать set-union
то, что он хочет, вы можете использовать list->set
для построения set
из list
:
(list->set (set-map ps
(lambda (subset) (set-add subset (set-first st)))))
В совокупности:
(define (power-set st)
(if (set-empty? st) (set (set))
(let ((ps (power-set (set-rest st))))
(set-union ps
(list->set
(set-map
ps
(lambda (subset) (set-add subset (set-first st)))))))))
Пара пробных прогонов:
scratch.rkt> (power-set (set 1 2))
(set (set 1) (set) (set 1 2) (set 2))
scratch.rkt> (power-set (set 1 2 3))
(set (set 1) (set 1 3) (set 1 3 2) (set 3 2) (set) (set 1 2) (set 2) (set 3))