Я думал в том, как реализовать эквивалент unfold
для следующего типа:Какое правильное определение `unfold` для немаркированного дерева?
data Tree a = Node (Tree a) (Tree a) | Leaf a | Nil
Это было не сразу очевидно, так как стандарт unfold
для списков возвращает значение и следующее семя. Для этого типа данных это не имеет смысла, поскольку нет значения, пока вы не достигнете листового узла. Таким образом, действительно имеет смысл возвращать новые семена или останавливаться со значением. Я использую это определение:
data Drive s a = Stop | Unit a | Branch s s deriving Show
unfold :: (t -> Drive t a) -> t -> Tree a
unfold fn x = case fn x of
Branch a b -> Node (unfold fn a) (unfold fn b)
Unit a -> Leaf a
Stop -> Nil
main = print $ unfold go 5 where
go 0 = Stop
go 1 = Unit 1
go n = Branch (n - 1) (n - 2)
Хотя это, похоже, работает, я не уверен, что так оно и должно быть. Итак, вот в чем вопрос: какой правильный способ это сделать?
Ум ... это похоже на единственную нормальную вещь, которую вы можете сделать. – dfeuer
Действительно? Я был уверен, что здесь делаю что-то глупое, но если это правильно, я могу просто удалить вопрос. – MaiaVictor
Вопрос нетривиален, и он может быть полезен другим. – chi