Data.Tree
включает функции unfoldTreeM_BF
и unfoldForestM_BF
для построения деревьев в ширину, сначала используя результаты монадических действий. Дерево unfolder можно легко написать с помощью лесной папки, поэтому я сосредоточусь на последнем:
unfoldForestM_BF :: Monad m =>
(b -> m (a, [b])) -> [b] -> m [Tree a]
Начиная со списка семян, он применяет функцию к каждому, генерируя действия, которые будут генерировать корни дерева и семена для следующего уровня разворачивания. Используемый алгоритм несколько строгий, поэтому использование unfoldForestM_BF
с монадой Identity
не совсем то же самое, что использовать чистую unfoldForest
. Я пытался выяснить, есть ли способ сделать это ленивым, не жертвуя временной привязкой O(n)
. Если (как мне предложил Эдвард Кемт) это невозможно, мне интересно, можно ли сделать это с более ограниченным типом, в частности требуя MonadFix
, а не Monad
. Концепция там была бы (каким-то образом) настроить указатели на результаты будущих вычислений при добавлении этих вычислений в список дел, поэтому, если они ленивы в эффектах более ранних вычислений, они будут доступны сразу.