
Quoth Justin Bailey, nevermore,
Above are all more examples of partial functions and function composition. I understand the first concept, but function composition escapes me somehow. What are the rules for partial functions getting arguments when they are eventually supplied? For example, in 'interpret_tests' I can see that the function (fromIntegral . interpret . compile) gets applied to the statement via 'checkResult', but it seems to me that fromIntegral should get teh argument (i.e. because I read it is '(fromIntegral (interpret (compile)))'). Clearly, I'm wrong. Do arguments get consumed by partially applied functions regardless of their "depth"?
The operators (.) and ($) are used to join functions together, but in slightly different ways. Taking your example above, we would use ($) to obtain nested functions:
fromIntegral $ interpret $ compile == fromIntegral (interpret (compile))
As you noted that doesn't seem right --- how does compile capture its input? Well, the (.) operator is slightly different. It captures variables and passes them into the 'innermost' function, a bit like this:
f . g = \x -> f (g x)
In this respect you can treat 'f . g' as a single functional entity which takes the same number and type of functions as 'g' and return whatever type 'f' returns. As in the type signature:
(.) :: (b -> c) -> (a -> b) -> a -> c
If it helps, think of something like
map (f . g . h) xs
as identical to the following (although obviously much more succinct and orders of magnitude clearer)
map (f') xs where f' = \x -> f (g (h x))
Cheers,
D.
--
Dougal Stanton