Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The existential type inferred from function literal is useless. #8515

Closed
scabug opened this issue Apr 18, 2014 · 5 comments
Closed

The existential type inferred from function literal is useless. #8515

scabug opened this issue Apr 18, 2014 · 5 comments

Comments

@scabug
Copy link

scabug commented Apr 18, 2014

Welcome to Scala version 2.10.3 (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_45).
Type in expressions to have them evaluated.
Type :help for more information.

scala> class C { trait T }
defined class C

scala> val c = new C
c: C = C@1130ed80

scala> val t1: c.T = (new { def apply(c: C) = new c.T {} })(c)
t1: c.T = $anon$2$$anon$1@23309add

scala> val t2: c.T = ({c: C => new c.T {} })(c)
<console>:9: error: type mismatch;
 found   : $anon where type $anon <: c.T
 required: c.T
       val t2: c.T = ({c: C => new c.T {} })(c)
                                            ^

scala> val f1: { def apply(c: C): c.T } = {c: C => new c.T {} }
<console>:9: error: type mismatch;
 found   : C => $anon forSome { type $anon <: c.T; val c: C }
 required: AnyRef{def apply(c: C): c.T}
       val f1: { def apply(c: C): c.T } = {c: C => new c.T {} }
                                                ^

The function literal is inferred to existential type {code} C => $anon forSome { type $anon <: c.T; val c: C } {code}, which looks complex, but it is no more special than simple C => C#T.

Could you infer the function literal to {code} (C => C#T) with { def apply(c: C): c.T } {code}

@scabug
Copy link
Author

scabug commented Apr 18, 2014

Imported From: https://issues.scala-lang.org/browse/SI-8515?orig=1
Reporter: @Atry
Affected Versions: 2.10.3, 2.10.4
Duplicates #4751

@scabug
Copy link
Author

scabug commented Apr 18, 2014

@retronym said:
The type of a a function literal is always of the form: FunctionN[A, B]

In your example B is an existential type.

Scala doesn't support dependent function types. There is a feature request for this in #4751. I will merge this ticket with that one, by adding your example to the comments of that ticket.

@scabug scabug closed this as completed Apr 18, 2014
@scabug
Copy link
Author

scabug commented Apr 18, 2014

@Atry said (edited on Apr 18, 2014 1:01:21 PM UTC):
No, dependent function types are not required to pass this example.

I assume the function literal is a shortcut of {code}new Function1[C, ] { { def apply(c: C): = new c.T {} } }{code}. I feel surprise when I found the different behavior between function literals and anonymous classes.

I guess referring the function literal to a compound type would suppress the compiler error.

@scabug
Copy link
Author

scabug commented Apr 18, 2014

@retronym said:
Section 6.3 of the spec explains how anonymous functions are type checked:

The type of the anonymous function is scala.Functionn[S1, ..., Sn, T ], where T is the packed type (§6.1) of e. T must be equivalent to a type which does not refer to any of the formal parameters xi .

The expansion to an anonymous subclass of FunctionN is only mentioned as the evaluation model:

The anonymous function is evaluated as the instance creation expression
new scala.Functionn[T1, ..., Tn, T] { def apply(x1: T1,...,xn: Tn): T = e
}

@scabug
Copy link
Author

scabug commented Apr 18, 2014

@Atry said:
You are right

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants