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.

Leave a Reply