Skip to content

Commit 251a7c4

Browse files
committed
More tests
1 parent f809ec4 commit 251a7c4

File tree

1 file changed

+79
-0
lines changed

1 file changed

+79
-0
lines changed

tests/run/polymorphic-functions.scala

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)