
On 2014-09-16 23:11, Dániel Arató wrote: Then I thought, "Why am I treating empty as a special value again?",
and wrote this instead:
stabilize :: Eq a => (a -> (b, a)) -> (c -> b -> c) -> c -> a -> (c, a) stabilize f g z d | d == d' = (z', d') | otherwise = stabilize f g z' d' where (val, d') = f d z' = g z val
This looks both really useful and extremely basic to me, so I'm wondering what the standard way to do the same thing might be.
I think you reinvented the 'unfoldr' function here: unfoldr :: (b -> Maybe (a, b)) -> b -> [a] It applies the given function to the second argument until the function returns Nothing, which correponds to your "d == d'" guard. You could use it to solve Problem 9 like pack :: Eq a => [a] -> [[a]] pack = unfoldr (\xs -> if null xs then Nothing else Just (span (== head xs) xs)) I think this looks like it does two things at once:
I looked at Foldable + foldr but the idea there seems to be to process a data structure _one_ element at a time.
It's true that a fold processes a data structure one element at a time, but you also have access to the accumulator, i.e. you can consider what you processed so far. I think you could solve Problem 9 using a foldr like pack :: Eq a => [a] -> [[a]] pack = foldr go [] where go x acc@(a:as) = if x == head a then (x:a):as else [x]:acc go x _ = [[x]] - Frerich