Reputation: 79
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
Upvotes: 3
Views: 108
Reputation: 120711
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.
Upvotes: 6