[Haskell-cafe] Re: Very crazy
andrewcoppin at btinternet.com
Tue Sep 25 06:40:50 EDT 2007
Aaron Denney wrote:
> On 2007-09-25, Andrew Coppin <andrewcoppin at btinternet.com> 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]
> 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?)
More information about the Haskell-Cafe