haskellpointfreeunfold

Unfold returning the last state of the accumulator


The unfold function in Haskell is very handy to create lists. Its definition is:

unfold :: (b -> Maybe (a, b)) -> b -> [a]

But I would like to get the last value of the accumulator used. A possible implementation is:

unfoldRest :: (b -> Maybe (a, b)) -> b -> ([a], b)
unfoldRest fct ini = go fct ini []
  where
    go f s acc =
      case f s of
        Nothing -> (acc, s)
        Just (a, b) -> go f b (acc ++ [a])

But I was wondering if there wasn't a way to do it with existing functions. In the end this:

countDown 0 = Nothing
countDown n = Just (n, n-1)
unfoldRest countDown 10

will return:

([10,9,8,7,6,5,4,3,2,1],0)

Because the iteration stopped when the accumulator value reached 0.


Solution

  • import Data.List
    
    unfoldr' :: (b -> Maybe (a, b)) -> b -> [(a, b)]
    unfoldr' f = unfoldr (fmap (\(a, b) -> ((a, b), b)) . f)
    

    will give you all the states of the accumulator. Then you can choose to look at whichever you want, including the last.