Skip to content

Instantly share code, notes, and snippets.

@danidiaz
Last active October 3, 2017 19:24
Show Gist options
  • Save danidiaz/e5debcaf531838eb6e2afd3ef3b34d60 to your computer and use it in GitHub Desktop.
Save danidiaz/e5debcaf531838eb6e2afd3ef3b34d60 to your computer and use it in GitHub Desktop.
(This answer pilfers wholesale from [this other answer][1] its example of histomorphism on lists.)
A simple —and not very compelling— example of chronomorphism would be a "safe tail" function for run-length-encoded lists:
tailRunLen :: [(Int,a)] -> Maybe [a]
tailRunLen = chrono alg coalg
where
alg v = case v of
Nil -> Nothing -- empty list
Cons _ (b :< x) -> case x of
Nil -> Just [] -- length 1 list
Cons a _ -> fmap (a:) b
coalg v = case v of
[] -> Nil
(i,a) : ias -> Cons a . foldr (.) id (replicate (pred i) $ Free . Cons a) $ Pure ias
The idea is that we use a futuromorphism to expand the list several items at a time
(as many layers as the run-length for the element) and then use a histomorphism that
lets us distinguish between the empty and 1-element list by "looking back two steps".
In action:
λ tailRunLen [(2,'a'),(3,'b')]
Just "abbb"
λ tailRunLen []
Nothing
[1]: https://stackoverflow.com/a/24895262/1364288
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment