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?
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.