Мы можем ввести вспомогательную функцию pick
, которая будет генерировать список из двух кортежей с выбранным элементом и возвращать оставшийся список. Мы можем реализовать это с помощью списка различий, но простая, менее эффективная реализация:
import Data.List(tails, inits)
pick :: [a] -> [(a, [a])]
pick vs = [(x, ws ++ xs) | (ws, (x:xs)) <- zip (inits vs) (tails vs) ]
Затем мы получаем:
Prelude Data.List> pick [2,3,4]
[(2,[3,4]),(3,[2,4]),(4,[2,3])]
Теперь мы можем изменить вашу down
функцию:
down :: a -> [a] -> Tree a
down y = Node y . map (uncurry down) . pick
Для данных данного примера мы получим:
Prelude Data.List> down 1 [2,3,4]
Node 1 [Node 2 [Node 3 [Node 4 []],Node 4 [Node 3 []]],Node 3 [Node 2 [Node 4 []],Node 4 [Node 2 []]],Node 4 [Node 2 [Node 3 []],Node 3 [Node 2 []]]]