How should I define or write my function in Haskell with function composition?

120 views Asked by At

I defined a function in Haskell,which is supposed to square and then add 1 to all numbers in a given list.I wanted to write that function with function composition but unfortunately it doesn't work with dot beetwen functions but it works when i write my functions with brackets.I don't understand why it doesn't work with dot or rather why doesn't it work with function composition?

square :: Int -> Int
square x = x * x

funSqr :: [Int] -> [Int]
funSqr xs = [(square x) | x <- xs]

funAdd1 :: [Int] -> [Int]
funAdd1 xs = [(x + 1) | x <- xs]

funFoldr :: [Int] -> Int 
funFoldr [] = 0
funFoldr (x:xs) = x + (funFoldr xs)

fun :: [Int] -> Int
fun xs = funFoldr(funAdd1(funSqr xs))

But

fun :: [Int] -> Int
fun xs = funFoldr.funAdd1.funSqr xs  --Why on earth doesn't it work ?
fun xs = funFoldr.funRek xs        --or rather this way?

Could someone lighten my path ?

Thanks a lot Asena

1

There are 1 answers

0
leftaroundabout On

Haskell parsing rules 101: function application binds more tightly than any infix operator. The amount of whitespace does not matter. So

funFoldr.funAdd1.funSqr xs
   ≡ funFoldr . funAdd1 . funSqr xs
   ≡ funFoldr . funAdd1 . (funSqr xs)

Now, funSqr xs is not a function anymore (just the result of applying a function to xs). You can't compose things that aren't functions.

What you meant to try is this, and it does indeed work:

(funFoldr.funAdd1.funSqr) xs

More commonly, this is written

funFoldr . funAdd1 . funSqr $ xs

or

funFoldr . funAdd1 $ funSqr xs

Alternative, you can avoid the funSqr xs grouping if you simply don't mention xs:

fun :: [Int] -> Int
fun = funFoldr . funAdd1 . funSqr

This is called point-free style.