Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 537
PierreBdR Avatar asked Dec 12 '22 06:12

PierreBdR


1 Answers

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.

like image 103
Tom Ellis Avatar answered Jan 02 '23 05:01

Tom Ellis