Function application (denoted by "juxtaposition", putting a function and its argument next to each other) has to be parsed somehow, and it needs to be either left-associative or right-associative in order to be parsed unambiguously.1
Function application is actually left-associative, so what you wrote is equivalent to
((((take 50) iterate) (* 2)) 1)
If it were right-associative instead, you would have
(take (50 (iterate ((* 2) 1))))
That's not what you wanted either, and it's much worse as a default choice: there are very few programs where a right-associative operator would feel more natural.
Since no uniform rule for parsing can produce the program you intend, it's necessary for you, the programmer, to tell haskell what you actually meant, by giving a hint in the form of $
or some parentheses.
As for why $
helps: it is defined to have a very low precedence in parsing, so that writing
take 50 $ iterate (* 2) 1
parses as
(take 50) $ ((iterate (* 2)) 1))
which is actually what you wanted.
1 Unambiguous parsing is a very desirable property for having understandable programs, and letting the typechecker decide how to parse things (as you suggest it might be able to do) would be quite a mess.