Where you're making a thought mistake is in even considering f ( f m s )
. That is not a subexpression of the for
definition: recall that function application is parsed from the left. So
for (m+1) n f ( f m s )
≡ (for (m+1)) n f ( f m s )
≡ (for (m+1) n) f ( f m s )
≡ (for (m+1) n f) ( f m s )
≇ (for (m+1) n ) (f ( f m s ))
≇ for (m+1) (n f ( f m s ))
≇ for ((m+1) n f ( f m s ))
The last inequality is probably most obvious, because you'd be applying the function (m+1)
to three arguments... that sure looks very unlikely.
If you need any "mental parenthesising" for understanding the function, it's normally best to put them around each function argument:
for (m+1) n f ( f m s )
≡ for (m+1)
(n)
(f)
(f m s)
and, if that helps you because it looks more like what you'd have in mainstream languages, you can also uncurry everything:
≅ for ( m+1, n, f, f(m,s) )
(though you'd better forget about that one quickly)
By the way: if you see a function applied to only one argument, it doesn't mean the function type has only one argument. In fact, the main strength of Haskell's curried syntax is that you can easily do partial application: e.g.
Prelude> :t take
take :: Int -> [a] -> [a]
Prelude> :t take 3
take 3 :: [a] -> [a]
Prelude> map (take 3) ["looooong", "even loonger", "terribly long"]
["loo","eve","ter"]
You see I've only applied take
to one argument, the other one is automatically taken from the list by map
.
Another example, with operator sections,
Prelude> :t (+)
(+) :: Num a => a -> a -> a
Prelude> :t (+ 1)
(+ 1) :: Num a => a -> a
Prelude> map (+ 1) [4,5,6]
[5,6,7]