Identical function and variable names and type inference

Hi all, Recently I wrote a function that takes a unique identifier that I called 'id'. I then tried to apply the 'id' function to it and GHC did not like that. But it should. For example in 'test' I have told the compiler that the id argument is an Int. So type inference should be able to determine the first 'id' in 'id id' couldn't possibly be an Int, but it complains. So I explicitly told the compiler the type of 'id' in test1 - this didn't work either. The final function 'test3' works as expected. Is there something I am not understand about the way type inference is supposed to work? test :: Int -> Int test id = id id test1 :: Int -> Int test1 id = idFunc id where idFunc :: a -> a idFunc = id test2 :: Int -> Int test2 myid@id = id myid test3 :: Int -> Int test3 id = Prelude.id id thanks ... -deech

On Wed, Sep 2, 2009 at 4:24 PM, aditya siram
Hi all, Recently I wrote a function that takes a unique identifier that I called 'id'. I then tried to apply the 'id' function to it and GHC did not like that. But it should.
For example in 'test' I have told the compiler that the id argument is an Int. So type inference should be able to determine the first 'id' in 'id id' couldn't possibly be an Int, but it complains. So I explicitly told the compiler the type of 'id' in test1 - this didn't work either. The final function 'test3' works as expected. Is there something I am not understand about the way type inference is supposed to work?
test :: Int -> Int test id = id id
Type inference plays no role in figuring out what your identifiers refer to. In the body of your function, the only identifier named "id" that's in scope is the argument to the function. There's a compiler warning for GHC you can use to be warned we you introduce identifiers which "shadow" existing identifiers, like in your function. Does my explanation make sense? Antoine

Ints can't make up the function part of an application, that must have type (a -> b). In the mean time, the reason it didn't accept test id = id id is because it must fix the argument id to only one type. It infers that id must have type (a -> b), from the fact that it appears in the function position, then sees it in the argument position, and infers that a = (a -> b) which obviously causes a problem. To resolve that problem, you need rank-2 polymorphism. Bob On 2 Sep 2009, at 23:24, aditya siram wrote:
Hi all, Recently I wrote a function that takes a unique identifier that I called 'id'. I then tried to apply the 'id' function to it and GHC did not like that. But it should.
For example in 'test' I have told the compiler that the id argument is an Int. So type inference should be able to determine the first 'id' in 'id id' couldn't possibly be an Int, but it complains. So I explicitly told the compiler the type of 'id' in test1 - this didn't work either. The final function 'test3' works as expected. Is there something I am not understand about the way type inference is supposed to work?
test :: Int -> Int test id = id id
test1 :: Int -> Int test1 id = idFunc id where idFunc :: a -> a idFunc = id
test2 :: Int -> Int test2 myid@id = id myid
test3 :: Int -> Int test3 id = Prelude.id id
thanks ... -deech
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners

On Wed, Sep 2, 2009 at 11:33 PM, Thomas Davie
Ints can't make up the function part of an application, that must have type (a -> b).
Well, I don't think that's strictly true. foo::Int can be argued to be a function that takes no arguments and return an Int. It is however very convenient to call such a function a "constant". However, that such a function actully is constant is far from guaranteed in most programming languages. It happens to be true in Haskell though, due to the strict separation between (proper) functions and "procedures" (functions with side effects, i.e. stuff in the IO monad).
In the mean time, the reason it didn't accept test id = id id is because it must fix the argument id to only one type. It infers that id must have type (a -> b), from the fact that it appears in the function position, then sees it in the argument position, and infers that a = (a -> b) which obviously causes a problem. To resolve that problem, you need rank-2 polymorphism.
Is that really correct? I suspect the only thing that causes the OP problems is scoping. If I understand you correctly I wouldn't be able to do the following: Prelude> let f x = x Prelude> :t f f :: t -> t Prelude> :t id id :: a -> a Prelude> :t id f id f :: t -> t Prelude> let g = id f Prelude> :t g g :: t -> t Prelude> id 5 5 Prelude> f 5 5 Prelude> g 5 5 Clearly that's not a problem at all. /M -- Magnus Therning (OpenPGP: 0xAB4DFBA4) magnus@therning.org Jabber: magnus@therning.org http://therning.org/magnus identi.ca|twitter: magthe

On Thu, Sep 3, 2009 at 8:35 AM, Magnus Therning
On Wed, Sep 2, 2009 at 11:33 PM, Thomas Davie
wrote: Ints can't make up the function part of an application, that must have type (a -> b).
Well, I don't think that's strictly true. foo::Int can be argued to be a function that takes no arguments and return an Int. It is however very convenient to call such a function a "constant". However, that such a function actully is constant is far from guaranteed in most programming languages. It happens to be true in Haskell though, due to the strict separation between (proper) functions and "procedures" (functions with side effects, i.e. stuff in the IO monad).
In the mean time, the reason it didn't accept test id = id id is because it must fix the argument id to only one type. It infers that id must have type (a -> b), from the fact that it appears in the function position, then sees it in the argument position, and infers that a = (a -> b) which obviously causes a problem. To resolve that problem, you need rank-2 polymorphism.
Is that really correct? I suspect the only thing that causes the OP problems is scoping. If I understand you correctly I wouldn't be able to do the following:
Prelude> let f x = x Prelude> :t f f :: t -> t Prelude> :t id id :: a -> a Prelude> :t id f id f :: t -> t Prelude> let g = id f Prelude> :t g g :: t -> t Prelude> id 5 5 Prelude> f 5 5 Prelude> g 5 5
Clearly that's not a problem at all.
Ah, sorry, I just remembered that the 'forall' is implicit (http://en.wikibooks.org/wiki/Haskell/Existentially_quantified_types). /M -- Magnus Therning (OpenPGP: 0xAB4DFBA4) magnus@therning.org Jabber: magnus@therning.org http://therning.org/magnus identi.ca|twitter: magthe

Am Mittwoch 02 September 2009 23:24:46 schrieb aditya siram:
Hi all, Recently I wrote a function that takes a unique identifier that I called 'id'. I then tried to apply the 'id' function to it and GHC did not like that. But it should.
For example in 'test' I have told the compiler that the id argument is an Int. So type inference should be able to determine the first 'id' in 'id id' couldn't possibly be an Int, but it complains. So I explicitly told the compiler the type of 'id' in test1 - this didn't work either. The final function 'test3' works as expected. Is there something I am not understand about the way type inference is supposed to work?
test :: Int -> Int test id = id id
test1 :: Int -> Int test1 id = idFunc id where idFunc :: a -> a idFunc = id
test2 :: Int -> Int test2 myid@id = id myid
test3 :: Int -> Int test3 id = Prelude.id id
thanks ... -deech
It's not type inference, it's scoping. By calling the function's parameter id, you shadow the name id, so within that scope each (unqualified) mention of the name id refers to the function's parameter. In test3, you use the qualified name Prelude.id, thus tell the compiler that it's not the parameter you want but the identity function.

On Wed, Sep 2, 2009 at 11:24 PM, aditya siram
Hi all, Recently I wrote a function that takes a unique identifier that I called 'id'. I then tried to apply the 'id' function to it and GHC did not like that. But it should.
For example in 'test' I have told the compiler that the id argument is an Int. So type inference should be able to determine the first 'id' in 'id id' couldn't possibly be an Int, but it complains. So I explicitly told the compiler the type of 'id' in test1 - this didn't work either. The final function 'test3' works as expected. Is there something I am not understand about the way type inference is supposed to work?
test :: Int -> Int test id = id id
test1 :: Int -> Int test1 id = idFunc id where idFunc :: a -> a idFunc = id
test2 :: Int -> Int test2 myid@id = id myid
test3 :: Int -> Int test3 id = Prelude.id id
How is the compiler supposed to differentiate between the situation where you really mean `id id` (and it type checks properly) and where you've mistakenly written `id id` (but it doesn't type check)? If that doesn't make you realise then think of it as your `id` shadowing the Prelude's, and that happens irrespective of the types. /M -- Magnus Therning (OpenPGP: 0xAB4DFBA4) magnus@therning.org Jabber: magnus@therning.org http://therning.org/magnus identi.ca|twitter: magthe
participants (5)
-
aditya siram
-
Antoine Latter
-
Daniel Fischer
-
Magnus Therning
-
Thomas Davie