File: currying_protocols.swift

package info (click to toggle)
swiftlang 6.0.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,519,992 kB
  • sloc: cpp: 9,107,863; ansic: 2,040,022; asm: 1,135,751; python: 296,500; objc: 82,456; f90: 60,502; lisp: 34,951; pascal: 19,946; sh: 18,133; perl: 7,482; ml: 4,937; javascript: 4,117; makefile: 3,840; awk: 3,535; xml: 914; fortran: 619; cs: 573; ruby: 573
file content (117 lines) | stat: -rw-r--r-- 2,495 bytes parent folder | download
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