haskell

Haskell dot operator with multiple parameters


I am doing exercise in fp-course
https://github.com/system-f/fp-course/blob/5e0848b4eacb3ddff65553ab5beb6447b73f61b3/src/Course/Applicative.hs#L357

The correct answer is

replicateA n ka = sequence $ replicate n ka

I cannot use (.) to do eta reduce as follow. Maybe because (.) only accept one parameter.

replicateA = sequence . replicate   -- wrong

Other example like flatMap

flatMap f xs = flatten $ map f xs
flatMap = flatten . map             -- wrong

How to use eta reduce when facing multiple parameters?


Solution

  • If you really want to convert this function to point-free notation, you'll need to use the (.) infix operator twice. Let's start with what you have.

    replicateA n ka = sequence $ replicate n ka
    

    Let's write this with explicit parentheses

        replicateA n ka = sequence $ (replicate n) ka
    

    Now this looks like function composition. Specifically, we're composing sequence and (replicate n).

        replicateA n ka = sequence . replicate n $ ka
    

    Now cancel off ka.

        replicateA n = sequence . replicate n
    

    Now operators are really just two-argument functions, so we can rewrite this as

        replicateA n = (.) sequence (replicate n)
    

    Again, this is function composition. We're just composing (.) sequence with replicate. So

        replicateA n = ((.) sequence) . replicate $ n
    

    Cancel off the n.

        replicateA = ((.) sequence) . replicate
    

    Now rewrite (.) sequence to use an operator section.

        replicateA = (sequence .) . replicate
    

    Is this more readable than the original? No. But it's point-free now.