Identical function and variable names and type inference

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

Identical function and variable names and type inference

aditya siram-2
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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.haskell.org/pipermail/beginners/attachments/20090902/b6ce09e2/attachment.html
Reply | Threaded
Open this post in threaded view
|

Identical function and variable names and type inference

Antoine Latter-2
On Wed, Sep 2, 2009 at 4:24 PM, aditya siram<[hidden email]> 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
>

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
Reply | Threaded
Open this post in threaded view
|

Identical function and variable names and type inference

Thomas Davie
In reply to this post by aditya siram-2
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
> [hidden email]
> http://www.haskell.org/mailman/listinfo/beginners

Reply | Threaded
Open this post in threaded view
|

Identical function and variable names and type inference

Daniel Fischer-4
In reply to this post by aditya siram-2
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.
Reply | Threaded
Open this post in threaded view
|

Identical function and variable names and type inference

Magnus Therning
In reply to this post by aditya siram-2
On Wed, Sep 2, 2009 at 11:24 PM, aditya siram<[hidden email]> 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

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
Reply | Threaded
Open this post in threaded view
|

Identical function and variable names and type inference

Magnus Therning
In reply to this post by Thomas Davie
On Wed, Sep 2, 2009 at 11:33 PM, Thomas Davie<[hidden email]> 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.

/M

--
Magnus Therning                        (OpenPGP: 0xAB4DFBA4)
magnus?therning?org          Jabber: magnus?therning?org
http://therning.org/magnus         identi.ca|twitter: magthe
Reply | Threaded
Open this post in threaded view
|

Identical function and variable names and type inference

Magnus Therning
On Thu, Sep 3, 2009 at 8:35 AM, Magnus Therning<[hidden email]> wrote:

> On Wed, Sep 2, 2009 at 11:33 PM, Thomas Davie<[hidden email]> 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