简体   繁体   中英

Unfolding non-empty structures to lists

I want to write Foldable.toList for a non-empty rose tree using an anamorphism, but it seems impossible to extract the last element:

import Data.Functor.Foldable

data RoseTree a = RoseNode a [RoseTree a]

ana5 :: RoseTree a -> [a]
ana5 = ana coalg5

coalg5 :: RoseTree a -> ListF a (RoseTree a)
coalg5 (RoseNode a []) = Nil
coalg5 (RoseNode a (RoseNode b1 b2:t)) = Cons a $ RoseNode b1 (b2 ++ t)

Is it indeed impossible and does it generalize to all non-empty structures?

Also (it's sort of an optional bonus question) is there a general rule to determine when Fix f -> Fix g can be implemented using f-algebras but not g-coalgebras?

Btw apomorphism worked:

coalg6 (RoseNode a []) = Cons a $ Left []
coalg6 (RoseNode a (RoseNode b1 b2:t)) = Cons a $ Right $ RoseNode b1 (b2 ++ t)

apo coalg6 has the same type as ana5 but doesn't lose one element

You've answered your own question: this operation is naturally structured as an apomorphism, not an anamorphism.

You can, of course, implement apo in terms of ana :

apo :: Functor f => (a -> f (Either (Fix f) a)) -> a -> Fix f
apo f = ana (either (fmap Left . unFix) f) . Right

(I came up with this by dualising " para in terms of cata ": para f = snd . cata (Fix . fmap fst &&& f) .)

You can just plug your coalg6 into this and get a coalgebra which does the same thing when given to ana :

ana5 = ana coalg5 . Right
    where coalg5 = either (fmap Left . unFix) coalg6

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM