On Tue, 2007-09-25 at 11:40 +0100, Andrew Coppin wrote: > Aaron Denney wrote: > > On 2007-09-25, Andrew Coppin <[EMAIL PROTECTED]> wrote: > > > >> OK, *now* I'm puzzled... Why does map . map type-check? > >> > > > > (map . map) = (.) map map > > > > (.) :: (a -> b) -> (b -> c) -> a -> c > > = (a -> b) -> (b -> c) -> (a -> c) > > > > The first two arguments of (.) are 1-argument functions. > > > > map :: (d -> e) -> [d] -> [e] > > = (d -> e) -> ([d] -> [e]) > > > > map is either a two argument function _or_ a function that takes one > > argument (a function) and returns a function. > > > > In this latter view, for the first argument, of (.), we need: > > > > a = d -> e > > b = [d] -> [e] > > > > And for the second we know > > b = [d] -> [e] > > so > > c = [[d]] -> [[e]] > > > > for everything to be consistent. > > > > It's much clearer when you think of map not as "running this function > > over this list", but rather "turning this function that operates on > > elements into a function that operates on lists". Doing that twice (by > > composing) turns a function that operates on elements into a function > > that operates on lists of lists. > > > > I just found it rather surprising. Every time *I* try to compose with > functions of more than 1 argument, the type checker complains. > Specifically, suppose you have > > foo = f3 . f2 . f1 > > Assuming those are all 1-argument functions, it works great. But if f1 > is a *two* argument function (like map is), the type checker refuses to > allow it, and I have to rewrite it as > > foo x y = f3 $ f2 $ f1 x y > > which is really extremely annoying... > > I'm just curiose as to why the type checker won't let *me* do it, but it > will let *you* do it. (Maybe it hates me?)
In f . g, if g takes two arguments, f has to take a function as the first argument (because that's what g returns). jcc _______________________________________________ Haskell-Cafe mailing list [email protected] http://www.haskell.org/mailman/listinfo/haskell-cafe
