
As I lay in bed last night, a curios fact occurred to me. (Yes, I don't get out very much...) Consider the map function: map :: (a -> b) -> [a] -> [b] There are two ways you can think about this function. First, you can see it as meaning map :: (a -> b) -> ([a] -> [b]) Which is beautifully symmetric. Alternatively, you can think about how you actually use it: map :: ((a -> b) -> [a]) -> [b] Now this got me thinking: is (->) associative? x_x Well now, let's consider a general 3-argument function: foo :: a -> b -> c -> d According to the rules, this is of course equivilent to foo :: a -> (b -> (c -> d)) If you understand what currying is and how it works, this makes perfect sense. Now let's bracket that the other way: foo :: ((a -> b) -> c) -> d Well, while that type *does* make sense, it's clearly a completely *different* type! So, clearly, (->) is not associative. Now I'm left wondering why you can bracket the type for map in two different ways, but not in general. Hmm...

POST
X-Face: H#SM:U1U-/6#NN83s6?Die557~]Dfifz~-|V:wSKGL6T-|!qk{U4/M7+k5Py!-{q=2Q/%0@
E29yc_kQC&^
User-Agent: Gnus/5.09 (Gnus v5.9.0) Emacs/21.4
Andrew Coppin
As I lay in bed last night, a curios fact occurred to me. (Yes, I don't get out very much...)
You probably ought to get out of bed from time to time, you know.
Consider the map function:
map :: (a -> b) -> [a] -> [b]
There are two ways you can think about this function. First, you can see it as meaning
map :: (a -> b) -> ([a] -> [b])
Which is beautifully symmetric. Alternatively, you can think about how you actually use it:
map :: ((a -> b) -> [a]) -> [b]
No, if you think like that, you're wrong! That would be a function that takes an object of type ((a->b) -> [a]) and returns a [b] (which if you think about it, would be an odd sort of function). (->) associates to the right. -- Jón Fairbairn Jon.Fairbairn@cl.cam.ac.uk

Jon Fairbairn wrote:
Andrew Coppin
writes: As I lay in bed last night, a curios fact occurred to me. (Yes, I don't get out very much...)
You probably ought to get out of bed from time to time, you know.
LOL! Thanks for the tip. :-P
Consider the map function:
map :: (a -> b) -> [a] -> [b]
There are two ways you can think about this function. First, you can see it as meaning
map :: (a -> b) -> ([a] -> [b])
Which is beautifully symmetric. Alternatively, you can think about how you actually use it:
map :: ((a -> b) -> [a]) -> [b]
No, if you think like that, you're wrong! That would be a function that takes an object of type ((a->b) -> [a]) and returns a [b] (which if you think about it, would be an odd sort of function). (->) associates to the right.
Hmm... I see the error of my ways. (Someone was asking my why map takes a function from a to b and returns a function from [a] to [b], rather than taking a function and a [a] and returning a [b]. And I pointed out that it's *both* of those things. And it seems that shortly after this point I confused myself! LOL.)

Andrew,
Which is beautifully symmetric. Alternatively, you can think about how you actually use it:
map :: ((a -> b) -> [a]) -> [b]
I am not following here: what do you mean? Clearly, this is not a valid typing for map. Moreover, modulo undefinedness, there are no functions with this typing. Cheers, Stefan

On Sun, May 27, 2007 at 02:10:40PM +0200, Stefan Holdermans wrote:
Andrew,
Which is beautifully symmetric. Alternatively, you can think about how you actually use it:
map :: ((a -> b) -> [a]) -> [b]
I am not following here: what do you mean? Clearly, this is not a valid typing for map. Moreover, modulo undefinedness, there are no functions with this typing.
map _ = [] Stefan

After a little too long trying, I managed to get code from which the type
system will infer that type, without using 'undefined':
*Main> :t map
map :: ((a -> a1) -> [a]) -> [a1]
import System.IO.Unsafe
import Data.IORef
import Prelude hiding (map)
import qualified Prelude as P
coerce a = unsafePerformIO (coerce' a)
where
ref = unsafePerformIO $ newIORef []
coerce' a = do
writeIORef ref [a]
b <- readIORef ref
return (head b)
map' a2b f = P.map a2b (f a2b)
map = map' coerce
On 27/05/07, Stefan Holdermans
map :: ((a -> b) -> [a]) -> [b]
I am not following here: what do you mean? Clearly, this is not a valid typing for map. Moreover, modulo undefinedness, there are no functions with this typing.
map _ = []
Ah, well, and that one, of course... :-)
Cheers,
Stefan _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

On 5/27/07, Andrew Coppin
map :: (a -> b) -> [a] -> [b] map :: (a -> b) -> ([a] -> [b])
Which is beautifully symmetric. Alternatively, you can think about how you actually use it:
map :: ((a -> b) -> [a]) -> [b]
No, now you're confusing things. The uncurried function looks like this: uncurry map :: (a -> b, [a]) -> [b] Note that map :: ( .... ) -> [b] only takes one argument, not two HTH /Thomas
participants (8)
-
Andrew Coppin
-
David House
-
Jon Fairbairn
-
Rodrigo Queiro
-
Stefan Holdermans
-
Stefan O'Rear
-
Thomas Schilling
-
Tomasz Zielonka