Search code examples
haskellpointfree

Point-free equivalent


I have this function from another SO question,

f :: Ord a => [a] -> [(a, Int)]
f xs = zipWith (\x ys -> (x, length $ filter (< x) ys)) xs (inits xs)

I'm trying to write it in point-free style,

f = flip (zipWith (\x -> (,) x . length . filter (< x))) =<< inits

Is it possible to get rid of that x ?


Solution

  • As a general rule: if a variable turns up more than once in an expression, it's probably not a good idea to make it point-free. If you're determined however, the least unreadable way is with the Arrow combinators, because that makes it pretty clear where the data flow is "split". For the xs I'd write

      uncurry (zipWith (...)) . (id &&& inits)
    

    For x, the same method yields

      zipWith ( curry $ uncurry(,) . (fst &&& length . uncurry filter . first(>)) )
    

    This is even longer than the (->)-monad solution that you've used and lambdabot suggests, but it looks far more organised.