tag:blogger.com,1999:blog-21500237.post4017885577779568121..comments2023-04-29T04:08:32.247-04:00Comments on Praise, Curse, and Recurse: Haskell for the Short Attention Span: Run-Length Encoding, Part 3Paul R. Pottshttp://www.blogger.com/profile/04401509483200614806noreply@blogger.comBlogger1125tag:blogger.com,1999:blog-21500237.post-39177483225874963872007-03-09T01:43:00.000-05:002007-03-09T01:43:00.000-05:00Speaking of warm fuzzy things, it's also possible ...Speaking of warm fuzzy things, it's also possible to write that last one as<BR/><BR/>unfoldr (\x -> guard (x /= "") >> return (splitAt 3 x))<BR/><BR/>Probably not any clearer, but it makes better use of unfoldr.<BR/><BR/>Personally, I like the following definition of unfoldr, which turns out equivalent to the original, but often more natural to use:<BR/><BR/>unfoldr' p f g = map f . takeWhile p . iterate g<BR/><BR/>(Now you perhaps see how my original definition fits in with this.)<BR/><BR/>Under that definition we can write triplify as:<BR/><BR/>unfoldr' (not . null) (take 3) (drop 3)<BR/><BR/>The reason why the two versions of unfoldr are equivalent is that:<BR/><BR/>unfoldr f = unfoldr' isJust (fst . fromJust) (f . snd . fromJust) . f<BR/>and<BR/>unfoldr' p f g = unfoldr (\x -> guard (p x) >> Just (f x, g x))<BR/><BR/>Despite the bit of awkwardness in reexpressing the original unfoldr, the 3 parameter version seems closer to most applications where you really need it.<BR/><BR/>Another example is computing digits of a number in say, base 10:<BR/><BR/>digits = unfoldr' (/= 0) (`mod` 10) (`div` 10)Cale Gibbardhttps://www.blogger.com/profile/02239068589033148700noreply@blogger.com