@@ -2,6 +2,8 @@ object Test extends App {
2
2
// Types
3
3
type F0 = [T ] => List [T ] => Option [T ]
4
4
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 ]
5
7
6
8
// Terms
7
9
val t0 = [T ] => (ts : List [T ]) => ts.headOption
@@ -11,4 +13,81 @@ object Test extends App {
11
13
val t1 = [F [_], G [_], T ] => (ft : F [T ], f : F [T ] => G [T ]) => f(ft)
12
14
val t1a : F1 = t1
13
15
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" )
14
93
}
0 commit comments