forked from swiftlang/swift
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcurrying_protocols.swift
117 lines (90 loc) · 2.43 KB
/
currying_protocols.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
// RUN: %target-run-simple-swift | %FileCheck %s
// REQUIRES: executable_test
enum Medal {
case Bronze, Silver, Gold
}
struct Steroids {}
protocol Gymnast {
func backflip(_ angle: Double) -> Self
func compete() -> (Medal) -> Self
func scandal() -> (Steroids) -> ()
static func currentYear() -> Int
}
final class Archimedes : Gymnast {
func backflip(_ angle: Double) -> Self {
print(angle >= 360 ? "Not in a thousand years" : "Ok")
return self
}
func compete() -> (Medal) -> Archimedes {
return { (m: Medal) in
print(m == .Gold ? "We won gold!" : "Try again next time")
return Archimedes()
}
}
func scandal() -> (Steroids) -> () {
return { s in print("Archimedes don't do that") }
}
static func currentYear() -> Int {
return -287
}
}
////
// Protocol-constrained archetype
////
func genericOlympicGames<T: Gymnast>(_ g1: T) -> T {
let f1: (T) -> (Double) -> T = T.backflip
let f2: (Double) -> T = f1(g1)
let g2: T = f2(180)
let f3: (Double) -> T = g2.backflip
let g3: T = f3(360)
let f4: (T) -> () -> (Medal) -> T = T.compete
let f5: () -> (Medal) -> T = f4(g3)
let f6: (Medal) -> T = f5()
let g4: T = f6(Medal.Silver)
let f7: () -> (Medal) -> T = g4.compete
let f8: (Medal) -> T = f7()
let g5: T = f8(Medal.Gold)
let f9: (T) -> () -> (Steroids) -> () = T.scandal
let f10: () -> (Steroids) -> () = f9(g5)
let f11: (Steroids) -> () = f10()
f11(Steroids())
let f12: () -> (Steroids) -> () = g5.scandal
let f13: (Steroids) -> () = f12()
f13(Steroids())
let f14: () -> Int = T.currentYear
print(f14())
let metatype: T.Type = T.self
let f15: () -> Int = metatype.currentYear
print(f15())
return g5
}
genericOlympicGames(Archimedes())
// CHECK: Ok
// CHECK: Not in a thousand years
// CHECK: Try again next time
// CHECK: We won gold!
// CHECK: Archimedes don't do that
// CHECK: Archimedes don't do that
// CHECK: -287
// CHECK: -287
////
// Existential
////
func olympicGames(_ g1: Gymnast) -> Gymnast {
// FIXME -- <rdar://problem/21391055>
#if false
let f1: Double -> Gymnast = g1.backflip
let g2: Gymnast = f1(180)
let f2: Medal -> Gymnast = g2.compete
let g4: Gymnast = f2()(Medal.Gold)
#endif
let f3: () -> (Steroids) -> () = g1.scandal
let f4: (Steroids) -> () = f3()
f4(Steroids())
let f5: () -> Int = type(of: g1).currentYear
print(f5())
return g1
}
olympicGames(Archimedes())
// CHECK: Archimedes don't do that
// CHECK: -287