@@ -2,6 +2,8 @@ object Test extends App {
22 // Types
33 type F0 = [T ] => List [T ] => Option [T ]
44 type F1 = [F [_], G [_], T ] => (F [T ], F [T ] => G [T ]) => G [T ]
5+ type F11 = [F [_[_]], G [_[_]], T [_]] => (F [T ], [U [_]] => F [U ] => G [U ]) => G [T ]
6+ type F2 = [T , U ] => (T , U ) => Either [T , U ]
57
68 // Terms
79 val t0 = [T ] => (ts : List [T ]) => ts.headOption
@@ -11,4 +13,81 @@ object Test extends App {
1113 val t1 = [F [_], G [_], T ] => (ft : F [T ], f : F [T ] => G [T ]) => f(ft)
1214 val t1a : F1 = t1
1315 assert(t1(List (1 , 2 , 3 ), (ts : List [Int ]) => ts.headOption) == Some (1 ))
16+
17+ val t11 = [F [_[_]], G [_[_]], T [_]] => (fl : F [T ], f : [U [_]] => F [U ] => G [U ]) => f(fl)
18+ val t11a : F11 = t11
19+ case class C11 [F [_]](is : F [Int ])
20+ case class D11 [F [_]](is : F [Int ])
21+ assert(t11[F = C11 ](C11 (List (1 , 2 , 3 )), [U [_]] => (c : C11 [U ]) => D11 (c.is)) == D11 (List (1 , 2 , 3 )))
22+
23+ val t2 = [T , U ] => (t : T , u : U ) => Left (t)
24+ val t2a : F2 = t2
25+ assert(t2(23 , " foo" ) == Left (23 ))
26+
27+ // Polymorphic idenity
28+ val pid = [T ] => (t : T ) => t
29+
30+ // Method with poly function argument
31+ def m [T ](f : [U ] => U => U , t : T ) = f(t)
32+ val m0 = m(pid, 23 )
33+
34+ // Constructor with poly function argument
35+ class C [T ](f : [U ] => U => U , t : T ) { val v : T = f(t) }
36+ val c0 = new C (pid, 23 )
37+
38+ // Function with poly function argument
39+ val mf = (f : [U ] => U => U , t : Int ) => f(t)
40+ val mf0 = mf(pid, 23 )
41+
42+ // Poly function with poly function argument
43+ val pf = [T ] => (f : [U ] => U => U , t : T ) => f(t)
44+ val pf0 = pf(pid, 23 )
45+
46+ // Poly function with AnyVal arguments
47+ val pf2 = [T ] => (f : [U ] => U => U , t : Int ) => f(t)
48+ val pf20 = pf2(pid, 23 )
49+
50+ // Implment/override
51+ val phd = [T ] => (ts : List [T ]) => ts.headOption
52+
53+ trait A {
54+ val is : List [Int ]
55+ def m1 (f : [T ] => List [T ] => Option [T ]): Option [Int ]
56+ def m2 (f : [T ] => List [T ] => Option [T ]): Option [Int ] = f(is)
57+ }
58+
59+ class B (val is : List [Int ]) extends A {
60+ def m1 (f : [T ] => List [T ] => Option [T ]): Option [Int ] = f(is)
61+ override def m2 (f : [T ] => List [T ] => Option [T ]): Option [Int ] = f(is)
62+ }
63+
64+ assert(new B (List (1 , 2 , 3 )).m1(phd) == Some (1 ))
65+ assert(new B (List (1 , 2 , 3 )).m2(phd) == Some (1 ))
66+
67+ // Overload
68+ class O (is : List [Int ]) {
69+ def m (f : [T ] => List [T ] => Option [T ]): (Option [Int ], Boolean ) = (f(is), true )
70+ def m (f : [T ] => (List [T ], T ) => Option [T ]): (Option [Int ], Boolean ) = (is.headOption.flatMap(f(is, _)), false )
71+ }
72+
73+ assert(new O (List (1 , 2 , 3 )).m(phd) == (Some (1 ), true ))
74+ assert(new O (List (1 , 2 , 3 )).m([T ] => (ts : List [T ], t : T ) => Some (t)) == (Some (1 ), false ))
75+
76+ // Dependent
77+ trait Entry [V ] { type Key ; val key : Key ; val value : V }
78+ def extractKey [V ](e : Entry [V ]): e.Key = e.key
79+ val md = [V ] => (e : Entry [V ]) => extractKey(e)
80+ val eis = new Entry [Int ] { type Key = String ; val key = " foo" ; val value = 23 }
81+ val v0 = md(eis)
82+ val v0a : String = v0
83+ assert(v0 == " foo" )
84+
85+ // Contextual
86+ trait Show [T ] { def show (t : T ): String }
87+ implicit val si : Show [Int ] =
88+ new Show [Int ] {
89+ def show (t : Int ): String = t.toString
90+ }
91+ val s = [T ] => (t : T ) => given (st : Show [T ]) => st.show(t)
92+ assert(s(23 ) == " 23" )
1493}
0 commit comments