[Haskell-beginners] What am I reinventing here

Frerich Raabe raabe at froglogic.com
Tue Sep 16 22:02:13 UTC 2014


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



More information about the Beginners mailing list