we7‘s study group (still aka Nerd Club) has moved onto a bit of Haskell with Learn You a Haskell for Great Good. The chapter on higher order functions introduces this definition:
numLongChains :: Int numLongChains = length (filter isLong (map chain [1..100])) where isLong xs = length xs > 15
For some reason I immediately wanted to factor the thing as a function taking isLong
as a parameter:
numLongChains` :: (Integral a) => ([a] -> Bool) -> Int numLongChains` isLong = length (filter isLong (map chain [1..100]))
(Forgive the backwards ‘prime’ symbols, apparently my blog’s syntax highlighting plugin can’t handle an apostrophe as part of a name.)
A quick check satisfied me that it worked
*Main> numLongChains 66 *Main> let longFunc xs = length xs > 15 *Main> numLongChains' longFunc 66
and then I carried on reading. It turns out to have been quite an instructive thing to do, as in the next sections I learned how to pass a lambda rather than a named function
*Main> numLongChains' (\xs -> length xs > 15) 66
and finally on to using function composition, giving, to my newly opened eyes, the most convenient way yet:
*Main> numLongChains' $ (> 15) . length 66
After that, we’re introduced to point-free (pointfree? point free?) style, and so I wondered how I’d turn my numLongChains'
function point-free. I struggled making no progress for a couple of hours, and had to give up until the group met to discuss the chapter. Chris Nix pointed out that I’d need a flip
on the filter
to get the arguments in the right order, and after a bit more playing I arrived at:
numLongChains```` :: (Integral a) => ([a] -> Bool) -> Int numLongChains```` = length . flip filter (map chain [1..100])
I’m really pleased to get to the right answer, but mostly I’m just shocked to discover a way of thinking about computation that’s so new and alien. I know it’d take me hours to come up with point-free versions of even simple functions. While trying to work out my example I found this topic which demonstrates a ton of techniques that I just hadn’t appreciated were out there. It’s less of an “Aha!” moment as things drop in to place, and more of a “Woah!” moment as a small crack appears and I glimpse strange beasts on the other side. I’m putting this aside for a while as we move on with the basics of Haskell, but I know I’ll be back someday.