Skip to content

Instantly share code, notes, and snippets.

@AndreasKostler
Last active September 23, 2015 06:32
Show Gist options
  • Save AndreasKostler/7645ba9d4ad16a84ea64 to your computer and use it in GitHub Desktop.
Save AndreasKostler/7645ba9d4ad16a84ea64 to your computer and use it in GitHub Desktop.
Shapeless inference puzzle
import shapeless._
trait Test {
def ex[InL <: HList, H, T <: HList](in : InL)(implicit isHCons: IsHCons1.Aux[InL, List[H], T])
val ii: List[Int]::List[Int]::HNil
ex(ii)
}
trait IsHCons1[L] { type H; type T <: HList}
object IsHCons1 {
type Aux[L <: HList, H0, T0 <: HList] = IsHCons1[L] { type H = H0; type T = T0 }
implicit def hlistIsHCons[H0, T0 <: HList]: Aux[H0 :: T0, H0, T0] = ???
}
import shapeless._
trait Test {
def ex[InL <: HList, L[_] <: List[_], H, T <: HList](in : InL)(implicit isHCons: IsHCons1.Aux[InL, L[H], T])
val ii: List[Int]::List[Int]::HNil
ex(ii)
}
trait IsHCons1[L] { type H; type T <: HList}
object IsHCons1 {
type Aux[L <: HList, H0, T0 <: HList] = IsHCons1[L] { type H = H0; type T = T0 }
implicit def hlistIsHCons[H0, T0 <: HList]: Aux[H0 :: T0, H0, T0] = ???
}
--- 1.log 2015-09-23 07:20:00.000000000 +0200
+++ 2.log 2015-09-23 07:20:02.000000000 +0200
@@ -1,236 +1,255 @@
|-- <empty> EXPRmode-POLYmode-QUALmode (site: package <root>)
| \-> <empty>.type
|-- shapeless EXPRmode-POLYmode-QUALmode (site: package <empty>)
| \-> shapeless.type
|-- class Test BYVALmode-EXPRmode (site: package <empty>)
| |-- $colon$colon[List[Int], $colon$colon[List[Int], HNil]] TYPEmode (site: value ii in Test)
| | |-- List[Int] TYPEmode (site: value ii in Test)
| | | |-- scala.`package` EXPRmode-POLYmode-QUALmode (site: value ii in Test)
| | | | \-> scala.type
| | | |-- Int TYPEmode (site: value ii in Test)
| | | | \-> Int
| | | \-> List[Int]
| | |-- $colon$colon[List[Int], HNil] TYPEmode (site: value ii in Test)
| | | |-- List[Int] TYPEmode (site: value ii in Test)
| | | | |-- scala.`package` EXPRmode-POLYmode-QUALmode (site: value ii in Test)
| | | | | \-> scala.type
| | | | |-- Int TYPEmode (site: value ii in Test)
| | | | | \-> Int
| | | | \-> List[Int]
| | | |-- HNil TYPEmode (site: value ii in Test)
| | | | \-> shapeless.HNil
| | | \-> shapeless.::[List[Int],shapeless.HNil]
| | \-> shapeless.::[List[Int],shapeless.::[List[Int],shapeless.HNil]]
| |-- def $init$ BYVALmode-EXPRmode (site: trait Test)
| | \-> [def $init$] ()Unit
-| |-- def ex[InL <: HList, H, T <: HList] BYVALmode-EXPRmode (site: trait Test)
+| |-- def ex[InL <: HList, L[_] <: List[_$1] forSome { <synthet... BYVALmode-EXPRmode (site: trait Test)
| | |-- scala.Unit TYPEmode (site: method ex in Test)
| | | \-> Unit
| | |-- InL TYPEmode (site: value in in Test)
| | | |-- <: HList TYPEmode (site: type InL in Test)
| | | | |-- HList TYPEmode (site: type InL in Test)
| | | | | \-> shapeless.HList
| | | | [adapt] <: shapeless.HList is now a TypeTree( <: shapeless.HList)
| | | | \-> <: shapeless.HList
| | | \-> InL
-| | |-- IsHCons1.Aux[InL, List[H], T] TYPEmode (site: value isHCons in Test)
+| | |-- IsHCons1.Aux[InL, L[H], T] TYPEmode (site: value isHCons in Test)
| | | |-- IsHCons1 EXPRmode-POLYmode-QUALmode (site: value isHCons in Test)
| | | | \-> IsHCons1.type
| | | |-- IsHCons1[L] { type H = H0; type T = T0 } TYPEmode (site: type Aux in IsHCons1)
| | | | |-- IsHCons1[L] TYPEmode (site: type Aux in IsHCons1)
| | | | | |-- L NOmode (site: type Aux in IsHCons1)
| | | | | | \-> L
| | | | | \-> IsHCons1[L]
| | | | |-- H0 TYPEmode (site: type H in <refinement>)
| | | | | \-> H0
| | | | |-- T0 TYPEmode (site: type T in <refinement>)
| | | | | \-> T0
| | | | |-- <: HList TYPEmode (site: type T0 in IsHCons1)
| | | | | |-- HList TYPEmode (site: type T0 in IsHCons1)
| | | | | | \-> shapeless.HList
| | | | | [adapt] <: shapeless.HList is now a TypeTree( <: shapeless.HList)
| | | | | \-> <: shapeless.HList
| | | | [adapt] IsHCons1[L] { type H = H0; type T = T0 } is now a TypeTree(IsHCons1[L]{type H = H0; type T = T0})
| | | | \-> IsHCons1[L]{type H = H0; type T = T0}
| | | |-- InL TYPEmode (site: value isHCons in Test)
| | | | \-> InL
-| | | |-- List[H] TYPEmode (site: value isHCons in Test)
-| | | | |-- scala.`package` EXPRmode-POLYmode-QUALmode (site: value isHCons in Test)
-| | | | | \-> scala.type
+| | | |-- L[H] TYPEmode (site: value isHCons in Test)
+| | | | |-- <: List[_$1] forSome { <synthetic> type _$1 } TYPEmode (site: type L in Test)
+| | | | | |-- List[_$1] forSome { <synthetic> type _$1 } TYPEmode (site: type L in Test)
+| | | | | | |-- _$1 BYVALmode-EXPRmode (site: type L in Test)
+| | | | | | | \-> [type _$1] _$1
+| | | | | | |-- List[_$1] TYPEmode (site: type L in Test)
+| | | | | | | |-- scala.`package` EXPRmode-POLYmode-QUALmode (site: type L in Test)
+| | | | | | | | \-> scala.type
+| | | | | | | |-- _$1 TYPEmode (site: type L in Test)
+| | | | | | | | \-> _$1
+| | | | | | | \-> List[_$1]
+| | | | | | \-> List[_]
+| | | | | [adapt] <: List is now a TypeTree( <: List[_])
+| | | | | \-> <: List[_]
| | | | |-- H TYPEmode (site: value isHCons in Test)
| | | | | \-> H
-| | | | \-> List[H]
+| | | | \-> L[H]
| | | |-- T TYPEmode (site: value isHCons in Test)
| | | | |-- <: HList TYPEmode (site: type T in Test)
| | | | | |-- HList TYPEmode (site: type T in Test)
| | | | | | \-> shapeless.HList
| | | | | [adapt] <: shapeless.HList is now a TypeTree( <: shapeless.HList)
| | | | | \-> <: shapeless.HList
| | | | \-> T
-| | | \-> IsHCons1.Aux[InL,List[H],T]
+| | | \-> IsHCons1.Aux[InL,L[H],T]
| | |-- <: HList TYPEmode (site: method ex in Test)
| | | |-- HList TYPEmode (site: method ex in Test)
| | | | \-> shapeless.HList
| | | [adapt] <: shapeless.HList is now a TypeTree( <: shapeless.HList)
| | | \-> <: shapeless.HList
+| | |-- <: List[_$1] forSome { <synthetic> type _$1 } TYPEmode (site: type L in Test)
+| | | |-- List[_$1] forSome { <synthetic> type _$1 } TYPEmode (site: type L in Test)
+| | | | |-- _$1 BYVALmode-EXPRmode (site: type L in Test)
+| | | | | \-> [type _$1] _$1
+| | | | |-- List[_$1] TYPEmode (site: type L in Test)
+| | | | | |-- scala.`package` EXPRmode-POLYmode-QUALmode (site: type L in Test)
+| | | | | | \-> scala.type
+| | | | | \-> List[_$1]
+| | | | \-> List[_]
+| | | [adapt] <: List[A] is now a TypeTree( <: List[_])
+| | | \-> <: List[_]
| | |-- <: HList TYPEmode (site: method ex in Test)
| | | |-- HList TYPEmode (site: method ex in Test)
| | | | \-> shapeless.HList
| | | [adapt] <: shapeless.HList is now a TypeTree( <: shapeless.HList)
| | | \-> <: shapeless.HList
| | |-- IsHCons1.Aux[L,H0,T0] TYPEmode (site: value isHCons in Test)
-| | | |-- List[H] TYPEmode (site: value isHCons in Test)
-| | | | |-- scala.`package` EXPRmode-POLYmode-QUALmode (site: value isHCons in Test)
-| | | | | \-> scala.type
-| | | | \-> List[H]
-| | | \-> IsHCons1.Aux[InL,List[H],T]
+| | | |-- L[_] TYPEmode (site: value isHCons in Test)
+| | | | \-> L[H]
+| | | \-> IsHCons1.Aux[InL,L[H],T]
| | |-- <: HList TYPEmode (site: type L in IsHCons1)
| | | |-- HList TYPEmode (site: type L in IsHCons1)
| | | | \-> shapeless.HList
| | | [adapt] <: shapeless.HList is now a TypeTree( <: shapeless.HList)
| | | \-> <: shapeless.HList
-| | \-> [def ex] [InL <: shapeless.HList, H, T <: shapeless.HList](in: InL)(implicit isHCons: IsHCons1.Aux[InL,List[H],T])Unit
+| | \-> [def ex] [InL <: shapeless.HList, L[_] <: List[_], H, T <: shapeless.HList](in: InL)(implicit isHCons: IsHCons1.Aux[InL,L[H],T])Unit
| |-- def ii BYVALmode-EXPRmode (site: trait Test)
| | |-- $colon$colon[List[Int], $colon$colon[List[Int], HNil]] TYPEmode (site: value ii in Test)
| | | |-- List[Int] TYPEmode (site: value ii in Test)
| | | | |-- scala.`package` EXPRmode-POLYmode-QUALmode (site: value ii in Test)
| | | | | \-> scala.type
| | | | |-- Int TYPEmode (site: value ii in Test)
| | | | | \-> Int
| | | | \-> List[Int]
| | | |-- $colon$colon[List[Int], HNil] TYPEmode (site: value ii in Test)
| | | | |-- List[Int] TYPEmode (site: value ii in Test)
| | | | | |-- scala.`package` EXPRmode-POLYmode-QUALmode (site: value ii in Test)
| | | | | | \-> scala.type
| | | | | |-- Int TYPEmode (site: value ii in Test)
| | | | | | \-> Int
| | | | | \-> List[Int]
| | | | |-- HNil TYPEmode (site: value ii in Test)
| | | | | \-> shapeless.HNil
| | | | \-> shapeless.::[List[Int],shapeless.HNil]
| | | \-> shapeless.::[List[Int],shapeless.::[List[Int],shapeless.HNil]]
| | \-> [def ii] => shapeless.::[List[Int],shapeless.::[List[Int],shapeless.HNil]]
| |-- ex(ii) BYVALmode-EXPRmode (site: value <local Test> in Test)
| | |-- ex BYVALmode-EXPRmode-FUNmode-POLYmode (silent: value <local Test> in Test)
undetParam added: type InL
+undetParam added: type L
undetParam added: type H
undetParam added: type T
-| | | [adapt] [InL <: shapeless.HList, H, T <: shapeless.HList](in: InL... adapted to [InL <: shapeless.HList, H, T <: shapeless.HList](in: InL...
-| | | \-> (in: InL)(implicit isHCons: IsHCons1.Aux[InL,List[H],T])Unit
+| | | [adapt] [InL <: shapeless.HList, L[_] <: List[_], H, T <: shapele... adapted to [InL <: shapeless.HList, L[_] <: List[_], H, T <: shapele...
+| | | \-> (in: InL)(implicit isHCons: IsHCons1.Aux[InL,L[H],T])Unit
| | |-- ii BYVALmode-EXPRmode-POLYmode (site: value <local Test> in Test)
| | | \-> shapeless.::[List[Int],shapeless.::[List[Int],shapeless.HNil]]
-| | solving for (InL: ?InL, H: ?H, T: ?T)
+| | solving for (InL: ?InL, L: ?L, H: ?H, T: ?T)
undetParam inferred: type InL as shapeless.::[List[Int],shapeless.::[List[Int],shapeless.HNil]]
-| | solving for (H: ?H, T: ?T)
+| | solving for (L: ?L, H: ?H, T: ?T)
| | |-- Aux[$colon$colon[H0, T0], H0, T0] TYPEmode (site: method hlistIsHCons in IsHCons1)
| | | |-- $colon$colon[H0, T0] TYPEmode (site: method hlistIsHCons in IsHCons1)
| | | | |-- H0 TYPEmode (site: method hlistIsHCons in IsHCons1)
| | | | | \-> H0
| | | | |-- T0 TYPEmode (site: method hlistIsHCons in IsHCons1)
| | | | | |-- <: HList TYPEmode (site: type T0 in IsHCons1)
| | | | | | |-- HList TYPEmode (site: type T0 in IsHCons1)
| | | | | | | \-> shapeless.HList
| | | | | | [adapt] <: shapeless.HList is now a TypeTree( <: shapeless.HList)
| | | | | | \-> <: shapeless.HList
| | | | | \-> T0
| | | | \-> shapeless.::[H0,T0]
| | | |-- H0 TYPEmode (site: method hlistIsHCons in IsHCons1)
| | | | \-> H0
| | | |-- T0 TYPEmode (site: method hlistIsHCons in IsHCons1)
| | | | \-> T0
| | | \-> IsHCons1.Aux[shapeless.::[H0,T0],H0,T0]
undetParam added: type H0
undetParam added: type T0
| | solving for (H0: ?H0, T0: ?T0)
-| | |-- [H0, T0 <: shapeless.HList]=> IsHCons1.Aux[shapeless.::[H... EXPRmode (silent: value <local Test> in Test) implicits disabled
-| | | \-> IsHCons1.Aux[shapeless.::[H0,T0],H0,T0]
-| | [adapt] [H0, T0 <: shapeless.HList]=> IsHCons1.Aux[shapeless.::[H... adapted to [H0, T0 <: shapeless.HList]=> IsHCons1.Aux[shapeless.::[H... based on pt IsHCons1.Aux[shapeless.::[List[Int],shapeless.::[List[Int],shapeless.HNil]],List[H],T]
-test.scala:6: error: could not find implicit value for parameter isHCons: IsHCons1.Aux[shapeless.::[List[Int],shapeless.::[List[Int],shapeless.HNil]],List[H],T]
- ex(ii)
- ^
-| | |-- [InL <: shapeless.HList, H, T <: shapeless.HList](in: InL... BYVALmode-EXPRmode (site solving: type H,type T: value <local Test> in Test)
-| | | solving for (H: ?H, T: ?T)
-| | | solving for (H: ?H, T: ?T)
-undetParam inferred: type H as Nothing
-undetParam inferred: type T as Nothing
-| | | \-> <error>
-| | [adapt] [InL <: shapeless.HList, H, T <: shapeless.HList](in: InL... adapted to [InL <: shapeless.HList, H, T <: shapeless.HList](in: InL...
-| | \-> <error>
+undetParam inferred: type H0 as List[Int]
+undetParam inferred: type T0 as shapeless.::[List[Int],shapeless.HNil]
+| | [adapt] [H0, T0 <: shapeless.HList]=> IsHCons1.Aux[shapeless.::[H... adapted to [H0, T0 <: shapeless.HList]=> IsHCons1.Aux[shapeless.::[H... based on pt IsHCons1.Aux[shapeless.::[List[Int],shapeless.::[List[Int],shapeless.HNil]],L[H],T]
+| | solving for (L: ?L, H: ?H, T: ?T)
+undetParam inferred: type L as List
+undetParam inferred: type H as Int
+undetParam inferred: type T as shapeless.::[List[Int],shapeless.HNil]
+| | |-- [InL <: shapeless.HList, L[_] <: List[_], H, T <: shapele... BYVALmode-EXPRmode (site: value <local Test> in Test)
+| | | \-> Unit
+| | [adapt] [InL <: shapeless.HList, L[_] <: List[_], H, T <: shapele... adapted to [InL <: shapeless.HList, L[_] <: List[_], H, T <: shapele...
+| | \-> Unit
| \-> [trait Test] Test
|-- class IsHCons1[L] BYVALmode-EXPRmode (site: package <empty>)
| |-- H BYVALmode-EXPRmode (site: trait IsHCons1)
| | \-> [type H] IsHCons1.this.H
| |-- T <: HList BYVALmode-EXPRmode (site: trait IsHCons1)
| | |-- <: HList TYPEmode (site: type T in IsHCons1)
| | | |-- HList TYPEmode (site: type T in IsHCons1)
| | | | \-> shapeless.HList
| | | [adapt] <: shapeless.HList is now a TypeTree( <: shapeless.HList)
| | | \-> <: shapeless.HList
| | |-- <: HList TYPEmode (site: trait IsHCons1)
| | | |-- HList TYPEmode (site: trait IsHCons1)
| | | | \-> shapeless.HList
| | | [adapt] <: shapeless.HList is now a TypeTree( <: shapeless.HList)
| | | \-> <: shapeless.HList
| | \-> [type T] IsHCons1.this.T
| \-> [trait IsHCons1] IsHCons1[L]
|-- object IsHCons1 BYVALmode-EXPRmode (site: package <empty>)
| |-- super EXPRmode-POLYmode-QUALmode (silent: <init> in IsHCons1)
| | |-- this EXPRmode (silent: <init> in IsHCons1)
| | | \-> IsHCons1.type
| | \-> IsHCons1.type
| |-- Aux[L <: HList, H0, T0 <: HList]IsHCons1[L] { type H = H0... BYVALmode-EXPRmode (site: object IsHCons1)
| | |-- <: HList TYPEmode (site: type Aux in IsHCons1)
| | | |-- HList TYPEmode (site: type Aux in IsHCons1)
| | | | \-> shapeless.HList
| | | [adapt] <: shapeless.HList is now a TypeTree( <: shapeless.HList)
| | | \-> <: shapeless.HList
| | |-- <: HList TYPEmode (site: type Aux in IsHCons1)
| | | |-- HList TYPEmode (site: type Aux in IsHCons1)
| | | | \-> shapeless.HList
| | | [adapt] <: shapeless.HList is now a TypeTree( <: shapeless.HList)
| | | \-> <: shapeless.HList
| | \-> [type Aux] IsHCons1.Aux[L,H0,T0]
| |-- def hlistIsHCons[H0, T0 <: HList] BYVALmode-EXPRmode (site: object IsHCons1)
| | |-- <: HList TYPEmode (site: method hlistIsHCons in IsHCons1)
| | | |-- HList TYPEmode (site: method hlistIsHCons in IsHCons1)
| | | | \-> shapeless.HList
| | | [adapt] <: shapeless.HList is now a TypeTree( <: shapeless.HList)
| | | \-> <: shapeless.HList
| | |-- Aux[$colon$colon[H0, T0], H0, T0] TYPEmode (site: method hlistIsHCons in IsHCons1)
| | | |-- $colon$colon[H0, T0] TYPEmode (site: method hlistIsHCons in IsHCons1)
| | | | \-> shapeless.::[H0,T0]
| | | \-> IsHCons1.Aux[shapeless.::[H0,T0],H0,T0]
| | |-- $qmark$qmark$qmark : pt=IsHCons1.Aux[shapeless.::[H0,T0],H0,T0] EXPRmode (site: method hlistIsHCons in IsHCons1)
| | | \-> Nothing
| | \-> [def hlistIsHCons] [H0, T0 <: shapeless.HList]=> IsHCons1.Aux[shapeless.::[H0,T0],H0,T0]
| \-> [object IsHCons1] IsHCons1.type
|-- HH0 BYVALmode-EXPRmode (site: <refinement>)
| \-> [type H] this.H
|-- TT0 BYVALmode-EXPRmode (site: <refinement>)
| \-> [type T] this.T
[[syntax trees at end of typer]] // test.scala
package <empty> {
import shapeless._;
abstract trait Test extends scala.AnyRef {
def /*Test*/$init$(): Unit = {
()
};
- def ex[InL <: shapeless.HList, H, T <: shapeless.HList](in: InL)(implicit isHCons: IsHCons1.Aux[InL,List[H],T]): Unit;
+ def ex[InL <: shapeless.HList, L[_] >: [_]Nothing <: [_]List[_], H, T <: shapeless.HList](in: InL)(implicit isHCons: IsHCons1.Aux[InL,L[H],T]): Unit;
<stable> <accessor> def ii: shapeless.::[List[Int],shapeless.::[List[Int],shapeless.HNil]];
- Test.this.ex[shapeless.::[List[Int],shapeless.::[List[Int],shapeless.HNil]], Nothing, Nothing](Test.this.ii)()
+ Test.this.ex[shapeless.::[List[Int],shapeless.::[List[Int],shapeless.HNil]], List, Int, shapeless.::[List[Int],shapeless.HNil]](Test.this.ii)(IsHCons1.hlistIsHCons[List[Int], shapeless.::[List[Int],shapeless.HNil]])
};
abstract trait IsHCons1[L] extends scala.AnyRef {
type H;
type T <: shapeless.HList
};
object IsHCons1 extends scala.AnyRef {
def <init>(): IsHCons1.type = {
IsHCons1.super.<init>();
()
};
type Aux[L <: shapeless.HList, H0, T0 <: shapeless.HList] = IsHCons1[L]{type H = H0; type T = T0};
implicit def hlistIsHCons[H0, T0 <: shapeless.HList]: IsHCons1.Aux[shapeless.::[H0,T0],H0,T0] = scala.this.Predef.???
}
}
-one error found
+warning: there was one feature warning; re-run with -feature for details
+one warning found
for i in 1 2; do cp $i.scala test.scala; scalac -Xprint:typer -Ymacro-debug-verbose -Ystop-after:typer -Ytyper-debug -Ymacro-expand:discard -classpath core/target/scala-2.11/classes test.scala 2>&1 | tee $i.log; done; diff -U1000 {1,2}.log > 3.log.diff
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment