Wednesday, June 10, 2009

Scan Golf!

I don't often use the list functionals scanl and scanr but here are two nice uses that I found yesterday:

List function tails with scanr:

scanrTails = scanr (:) []


Unfortunately inits is harder as it needs to snoc the list, it has a slow definition with (++):

scanlInits = scanl snoc [] where
snoc xs x = xs++[x]


Or a more efficient one with Hughes lists (see diff list on Hackage):

type H a = [a] -> [a]

out :: H a -> [a]
out f = f []

snoc :: H a -> a -> H a
snoc f a = f . (a:)

scanlInits' :: [a] -> [[a]]
scanlInits' = map out . scanl snoc id


I had defined tails as a paramorphism which lead me to see it as a scan:

paraTails = para phi [[]] where
phi e (fwd,acc) = (e:fwd):acc


Para's definition is:


-- paramorphism (generalizes cata)
para :: (a -> ([a], b) -> b) -> b -> [a] -> b
para phi b = step
where step [] = b
step (e:es) = phi e (es, step es)

Blog Archive

About Me

My photo
Disambiguating biog as there are a few Stephen Tetley's in the world. I'm neither a cage fighter or yachtsman. I studied Fine Art in the nineties (foundation Bradford 1992, degree Cheltenham 1992 - 95) then Computing part-time at Leeds Met graduating in 2003. I'm the Stephen Tetley on Haskell Cafe and Stackoverflow.