Confusing type error -- found: X, required: X?

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

Confusing type error -- found: X, required: X?

Aaron Harnly-2-2
The following type error confuses the heck out of me.

It appears to be saying that it requires type 'X', but instead found  
foo.type (with underlying type 'X'). If the underlying type is the  
required type, wherein lies the problem?

Or do y'all suspect that this is exposing some weird bug in the  
handling of existentials? (I'd be more inclined to believe that I'm  
doing something wrong that I don't understand, though.)

TIA,
aaron

[WARNING]EntityMappings.scala:39: error: type mismatch;
[WARNING]  found   : attr.type (with underlying type Attribute[E,_$9]  
forSome { type _$9 })
[WARNING]  required: Attribute[E,_$9] where type _$9
[WARNING] attr -> _customAttributeMappings.getOrElse( attr,
[WARNING]                         ^
[WARNING] one error found


Reply | Threaded
Open this post in threaded view
|

Re: Confusing type error -- found: X, required: X?

Martin Odersky
On Fri, Jul 18, 2008 at 4:11 PM, Aaron Harnly
<[hidden email]> wrote:
> The following type error confuses the heck out of me.
>
> It appears to be saying that it requires type 'X', but instead found
> foo.type (with underlying type 'X'). If the underlying type is the required
> type, wherein lies the problem?
>
It seems to be a real error. Required is:

Attribute[E,_$9] where type _$9

This means that _$9 is some unknown type, *which you are not free to choose*

Found was:

Attribute[E,_$9] forSome { type _$9 }

That means _$9 is not known at the point. So because it is now known,
one cannot assume it is the other _$9.

In logic terms, it's equivalent to the following statement:

If you have a

  exists x. P(x)

you cannot conclude

  P(x)

Cheers

 -- Martin
Reply | Threaded
Open this post in threaded view
|

Re: Confusing type error -- found: X, required: X?

Aaron Harnly-2-2
martin odersky <martin.odersky@...> writes:

> It seems to be a real error. Required is:
> Attribute[E,_$9] where type _$9
>
> This means that _$9 is some unknown type,
> *which you are not free to choose*
>
> Found was:
> Attribute[E,_$9] forSome { type _$9 }
>
> That means _$9 is not known at the point. So because it is now known,
> one cannot assume it is the other _$9.

Thanks Martin.
It appears that (at least one) cause of this error is the
use of the -> operator to generate tuples. Which I, and many others, use
all the time, but apparently doesn't interact well with existentials. As
ever, tip o' the hat to David McIver for talking this through with me on
IRC.

Consider this bit of code, which compiles fine:
// -------------------
trait Foo[T]
def getAFoo: Option[Foo[_]] = Some(new Foo[Int] {})

def usePairs(foo: Set[(Foo[_],Int)]) = "used pairs"

def producePairs = usePairs( Set(
        List(1,2,3).flatMap(x =>
                getAFoo.map(foo => (foo, x) )
        ) : _*
))
// -------------------

Now, change the (foo, x) to: foo -> x, and we get:

 found   : foo.type (with underlying type Foo[_$1] forSome { type _$1 })
 required: Foo[_$1] where type _$1
                getAFoo.map(foo => foo -> x )
                                    ^
one error found

Yikes!
~aaron




Reply | Threaded
Open this post in threaded view
|

Re: Re: Confusing type error -- found: X, required: X?

James Iry-2
Seems strange

trait Foo[A]
val foo:Foo[_] = new Foo[Int]{}
arrow2Assoc(foo)
//res1: ArrowAssoc[Foo[_$1]] forSome { type _$1 } = scala.Predef$ArrowAssoc@16c848f

case class Test[A](value:A)
Test(foo)

//res1: 
Test[Foo[_$1]] forSome { type _$1 } = Test([hidden email])

The scoping seems strange. Shouldn't that be
Test[Foo[_$1] forSome { type _$1 }] ?


On Fri, Jul 25, 2008 at 10:21 AM, Aaron Harnly <[hidden email]> wrote:
martin odersky <martin.odersky@...> writes:
> It seems to be a real error. Required is:
> Attribute[E,_$9] where type _$9
>
> This means that _$9 is some unknown type,
> *which you are not free to choose*
>
> Found was:
> Attribute[E,_$9] forSome { type _$9 }
>
> That means _$9 is not known at the point. So because it is now known,
> one cannot assume it is the other _$9.

Thanks Martin.
It appears that (at least one) cause of this error is the
use of the -> operator to generate tuples. Which I, and many others, use
all the time, but apparently doesn't interact well with existentials. As
ever, tip o' the hat to David McIver for talking this through with me on
IRC.

Consider this bit of code, which compiles fine:
// -------------------
trait Foo[T]
def getAFoo: Option[Foo[_]] = Some(new Foo[Int] {})

def usePairs(foo: Set[(Foo[_],Int)]) = "used pairs"

def producePairs = usePairs( Set(
       List(1,2,3).flatMap(x =>
               getAFoo.map(foo => (foo, x) )
       ) : _*
))
// -------------------

Now, change the (foo, x) to: foo -> x, and we get:

 found   : foo.type (with underlying type Foo[_$1] forSome { type _$1 })
 required: Foo[_$1] where type _$1
               getAFoo.map(foo => foo -> x )
                                   ^
one error found

Yikes!
~aaron





Reply | Threaded
Open this post in threaded view
|

Re: Re: Confusing type error -- found: X, required: X?

David MacIver
On Fri, Jul 25, 2008 at 6:33 PM, James Iry <[hidden email]> wrote:

> Seems strange
>
> trait Foo[A]
> val foo:Foo[_] = new Foo[Int]{}
> arrow2Assoc(foo)
> //res1: ArrowAssoc[Foo[_$1]] forSome { type _$1 } =
> scala.Predef$ArrowAssoc@16c848f
>
> case class Test[A](value:A)
> Test(foo)
>
> //res1: Test[Foo[_$1]] forSome { type _$1 } = Test($anon$1@1b8cdd5)
>
> The scoping seems strange. Shouldn't that be Test[Foo[_$1] forSome { type
> _$1 }] ?

Note also:

scala> Test[Foo[_]](foo)
res2: Test[Foo[_$1] forSome { type _$1 }] = Test($anon$1@16bf0aa)

So it can be given the correct type, it's just that the type
inferencer is inferring too general a type.