├── PartialOperatorApplication.xcodeproj
├── project.xcworkspace
│ └── contents.xcworkspacedata
└── project.pbxproj
├── PartialOperatorApplication
├── PartialOperatorApplication.h
└── Info.plist
├── PartialOperatorApplicationTests
├── Info.plist
└── PartialOperatorApplicationTests.swift
├── .gitignore
├── README.md
└── Sources
└── PartialOperatorApplication.swift
/PartialOperatorApplication.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/PartialOperatorApplication/PartialOperatorApplication.h:
--------------------------------------------------------------------------------
1 | //
2 | // PartialOperatorApplication.h
3 | // PartialOperatorApplication
4 | //
5 | // Created by Michael Pangburn on 2/5/18.
6 | // Copyright © 2018 Michael Pangburn. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | //! Project version number for PartialOperatorApplication.
12 | FOUNDATION_EXPORT double PartialOperatorApplicationVersionNumber;
13 |
14 | //! Project version string for PartialOperatorApplication.
15 | FOUNDATION_EXPORT const unsigned char PartialOperatorApplicationVersionString[];
16 |
17 | // In this header, you should import all the public headers of your framework using statements like #import
18 |
19 |
20 |
--------------------------------------------------------------------------------
/PartialOperatorApplicationTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 |
22 |
23 |
--------------------------------------------------------------------------------
/PartialOperatorApplication/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | $(CURRENT_PROJECT_VERSION)
21 | NSPrincipalClass
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Xcode
2 | #
3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
4 |
5 | ## Build generated
6 | build/
7 | DerivedData/
8 |
9 | ## Various settings
10 | *.pbxuser
11 | !default.pbxuser
12 | *.mode1v3
13 | !default.mode1v3
14 | *.mode2v3
15 | !default.mode2v3
16 | *.perspectivev3
17 | !default.perspectivev3
18 | xcuserdata/
19 |
20 | ## Other
21 | *.moved-aside
22 | *.xccheckout
23 | *.xcscmblueprint
24 |
25 | ## Obj-C/Swift specific
26 | *.hmap
27 | *.ipa
28 | *.dSYM.zip
29 | *.dSYM
30 |
31 | ## Playgrounds
32 | timeline.xctimeline
33 | playground.xcworkspace
34 |
35 | # Swift Package Manager
36 | #
37 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies.
38 | # Packages/
39 | # Package.pins
40 | # Package.resolved
41 | .build/
42 |
43 | # CocoaPods
44 | #
45 | # We recommend against adding the Pods directory to your .gitignore. However
46 | # you should judge for yourself, the pros and cons are mentioned at:
47 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
48 | #
49 | # Pods/
50 |
51 | # Carthage
52 | #
53 | # Add this line if you want to avoid checking in source code from Carthage dependencies.
54 | # Carthage/Checkouts
55 |
56 | Carthage/Build
57 |
58 | # fastlane
59 | #
60 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
61 | # screenshots whenever they are needed.
62 | # For more information about the recommended setup visit:
63 | # https://docs.fastlane.tools/best-practices/source-control/#source-control
64 |
65 | fastlane/report.xml
66 | fastlane/Preview.html
67 | fastlane/screenshots
68 | fastlane/test_output
69 |
--------------------------------------------------------------------------------
/PartialOperatorApplicationTests/PartialOperatorApplicationTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PartialOperatorApplicationTests.swift
3 | // PartialOperatorApplicationTests
4 | //
5 | // Created by Michael Pangburn on 2/5/18.
6 | // Copyright © 2018 Michael Pangburn. All rights reserved.
7 | //
8 |
9 | import XCTest
10 | @testable import PartialOperatorApplication
11 |
12 | class PartialOperatorApplicationTests: XCTestCase {
13 |
14 | class Reference: Equatable {
15 | static func == (lhs: Reference, rhs: Reference) -> Bool {
16 | return lhs === rhs
17 | }
18 | }
19 |
20 | func testPartialEquality() {
21 | let numbers = [1, 2, 3, 3, 3, 4, 5]
22 | XCTAssert(numbers.filter(==3) == [3, 3, 3])
23 | XCTAssert(numbers.filter(3==) == [3, 3, 3])
24 | XCTAssert(numbers.filter(!=3) == [1, 2, 4, 5])
25 | XCTAssert(numbers.filter(~=3) == [3, 3, 3])
26 | XCTAssert(numbers.filter(3~=) == [3, 3, 3])
27 | }
28 |
29 | func testPartialIdentityEquality() {
30 | let (firstReference, secondReference) = (Reference(), Reference())
31 | let dummies = [firstReference, firstReference, secondReference, secondReference]
32 | XCTAssert(dummies.filter(===firstReference) == [firstReference, firstReference])
33 | XCTAssert(dummies.filter(firstReference===) == [firstReference, firstReference])
34 | XCTAssert(dummies.filter(!==firstReference) == [secondReference, secondReference])
35 | }
36 |
37 | func testPartialComparison() {
38 | let numbers = Array(1...10)
39 | XCTAssert(numbers.filter(>5) == Array(6...10))
40 | XCTAssert(numbers.filter(5<=) == Array(5...10))
41 | XCTAssert(numbers.filter(>=8) == Array(8...10))
42 | XCTAssert(numbers.filter(8<) == Array(9...10))
43 | XCTAssert(numbers.filter(<=3) == Array(1...3))
44 | XCTAssert(numbers.filter(3>=) == Array(1...3))
45 | }
46 |
47 | func testPartialNumericOperations() {
48 | let numbers = Array(1...10)
49 | XCTAssert(numbers.map(+2) == Array(3...12))
50 | XCTAssert(numbers.map(2+) == Array(3...12))
51 | XCTAssert(numbers.map(11-) == Array(1...10).reversed())
52 | XCTAssert(numbers.map(*2) == Array(stride(from: 2, through: 20, by: 2)))
53 | XCTAssert(numbers.map(2*) == Array(stride(from: 2, through: 20, by: 2)))
54 | }
55 |
56 | func testPartialFloatingPointOperations() {
57 | let numbers = Array(stride(from: 1.0, through: 5.0, by: 1.0))
58 | XCTAssert(numbers.map(/2) == Array(stride(from: 0.5, through: 2.5, by: 0.5)))
59 | XCTAssert(numbers.map(2/) == [2.0, 1.0, 2.0 / 3.0, 0.5, 0.4])
60 | }
61 |
62 | func testPartialBinaryIntegerOperations() {
63 | let numbers = Array(1...5)
64 | XCTAssert(numbers.map(/2) == [0, 1, 1, 2, 2])
65 | XCTAssert(numbers.map(%2) == [1, 0, 1, 0, 1])
66 | let factorsOfTwelve = [1, 2, 3, 4, 6, 12]
67 | XCTAssert(factorsOfTwelve.map(12/) == Array(factorsOfTwelve).reversed())
68 | XCTAssert(factorsOfTwelve.map(10%) == [0, 0, 1, 2, 4, 10])
69 | }
70 |
71 | func testPartialBoolOperations() {
72 | let bools = [true, false, true, false]
73 | XCTAssert(bools.map(&&true) == bools)
74 | XCTAssert(bools.map(true&&) == bools)
75 | XCTAssert(bools.map(&&false) == Array(repeating: false, count: bools.count))
76 | XCTAssert(bools.map(false&&) == Array(repeating: false, count: bools.count))
77 | XCTAssert(bools.map(||true) == Array(repeating: true, count: bools.count))
78 | XCTAssert(bools.map(true||) == Array(repeating: true, count: bools.count))
79 | XCTAssert(bools.map(||false) == bools)
80 | XCTAssert(bools.map(false||) == bools)
81 | }
82 |
83 | func testPartialNilCoalescing() {
84 | let maybeNumbers: [Int?] = [1, 2, nil, 4, nil, 6]
85 | XCTAssert(maybeNumbers.map(??100) == [1, 2, 100, 4, 100, 6])
86 | }
87 |
88 | func testPartialsInSwitch() {
89 | func signum(_ x: Int) -> Int {
90 | switch x {
91 | case not(>=0):
92 | return -1
93 | case ==0:
94 | return 0
95 | case >0:
96 | return 1
97 | default:
98 | fatalError()
99 | }
100 | }
101 |
102 | XCTAssert(signum(-5) == -1)
103 | XCTAssert(signum(0) == 0)
104 | XCTAssert(signum(3) == 1)
105 | }
106 | }
107 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Partially Applied Operators
2 |
3 | [](#)
4 | [](https://twitter.com/pangburnout)
5 |
6 | A thought experiment in bringing the semantics of Haskell's partial application of operators to Swift.
7 |
8 | ## Background
9 | In functional programming languages, [currying](https://en.wikipedia.org/wiki/Currying) enables the partial application of functions. For example, consider a function `add` that takes two integer arguments and returns their sum. Currying allows a single argument to be passed to `add` to create a new function. This new function takes only a single integer argument and returns its sum with the first argument passed. When `add` is passed only a single argument, it is partially applied.
10 |
11 | In a language like Haskell, functions that take multiple arguments are inherently curried. For example, here is the signature of `add` in Haskell:
12 |
13 | ```haskell
14 | add :: Int -> Int -> Int
15 | ```
16 |
17 | Notice how the return `->` separates not just the arguments from the return type, but also the arguments from one another. In Swift, we might think to write the signature of `add` like so:
18 |
19 | ```swift
20 | func add(_ x: Int, _ y: Int) -> Int
21 | ```
22 |
23 | However, when defined in this manner, `add` is not curried. To make use of `add` as a curried function in Swift, we would write its signature in a different way:
24 |
25 | ```swift
26 | func add(_ x: Int) -> (_ y: Int) -> Int
27 | ```
28 |
29 | This curried `add` would be used slightly differently from how we defined it initially:
30 |
31 | ```swift
32 | // Using definition 1:
33 | add(2, 4) // 6
34 |
35 | // Using definition 2:
36 | add(2)(4) // 6
37 | ```
38 |
39 | While the extra pair of parentheses is unappealing, we gain powerful functionality through currying:
40 |
41 | ```swift
42 | let add2 = add(2)
43 | add2(4) // 6
44 | add2(10) // 12
45 | ```
46 |
47 | In this way, currying allows for composable, reusable functions.
48 |
49 | Since operators are really just infix functions with special symbols, they can also be partially applied. Partially appplied operators are especially useful for mapping over or filtering a list:
50 |
51 | ```haskell
52 | numbers = [1, 2, 3, 4, 5]
53 | map (+2) numbers -- [3, 4, 5, 6, 7]
54 | filter (>=3) numbers -- [3, 4, 5]
55 | ```
56 |
57 | In Swift, we can do something similar using trailing closure syntax:
58 |
59 | ```swift
60 | let numbers = [1, 2, 3, 4, 5]
61 | numbers.map { $0 + 2 } // [3, 4, 5, 6, 7]
62 | numbers.filter { $0 >= 3 } // [3, 4, 5]
63 | ```
64 |
65 | However, there is a key difference here: in the Haskell example, we make use of operators without explicitly identifying their operands—this is called [point-free style](https://en.wikipedia.org/wiki/Tacit_programming). In Swift, we identify the operand in the map or filter with `$0`.
66 |
67 | The goal of this project is to bring the semantics of Haskell's partially applied operators to Swift:
68 |
69 | ```swift
70 | let numbers = [1, 2, 3, 4, 5]
71 | numbers.map(+2) // [3, 4, 5, 6, 7]
72 | numbers.filter(>=3) // [3, 4, 5]
73 | ```
74 |
75 | ## Implementation
76 | The built-in operators defined in the Swift Standard Library are not curried. We could curry them using a [helper function](https://github.com/pointfreeco/swift-prelude/blob/b23463ebd7c1ce11600f86cbcb8165098fd44693/Sources/Prelude/Curry.swift), but calling `curry` whenever we partially apply an operator would be inelegant and obscure our intent.
77 |
78 | Instead, we define "unary" versions of the infix operators in order to partially apply them. For example, our `add` example from above becomes
79 |
80 | ```swift
81 | prefix func + (rhs: T) -> (_ lhs: T) -> T {
82 | return { $0 + rhs }
83 | }
84 | ```
85 |
86 | Where possible, we define both prefix and postfix versions of operators:
87 |
88 | ```swift
89 | postfix func + (lhs: T) -> (_ rhs: T) -> T {
90 | return { lhs + $0 }
91 | }
92 | ```
93 |
94 | Defining both versions is most important for operations that are not commutative, such as division.
95 |
96 | ## Limitations
97 | Some limitations are imposed on operator declarations in certain contexts:
98 |
99 | - The less-than symbol `<` cannot be used as a prefix operator, and the greater-than symbol `>` cannot be used as a postfix operator. These symbols are reserved in these contexts to avoid compiler confusion in identifying generics.
100 | - An overloaded prefix `-` on Numeric types is not properly interpreted by the compiler. Interestingly, `+` does not have this problem despite also being already defined as a prefix operator on Numeric types.
101 | - Prefix `&` is reserved for passing variables as inout parameters, so it cannot be used as a prefix in partially applying the bitwise AND operator.__*__
102 | - Postfix operators cannot begin with '!' because of its use with Optionals, which prevents the postfix definitions of `!=` and `!==`.__*__
103 | - Postfix operators cannot begin with '?' because of its use with Optionals, which prevents the postfix definition of `??`.
104 |
105 | __*__ In practice, the restrictions on these operators are trivial since their operations are commutative, and either their prefix or postfix version can be implemented without issues.
106 |
107 | ## Looking Forward
108 | While [SE-002](https://github.com/apple/swift-evolution/blob/master/proposals/0002-remove-currying.md) removed previous syntax for currying, it also included some brief thoughts on [the future of currying in Swift](https://github.com/apple/swift-evolution/blob/master/proposals/0002-remove-currying.md#alternatives-considered). While we have yet to see movement on this front, inherently curried functions would have significant implications for the functional Swift community. Hopefully, the syntax introduced through this project will one day be native to Swift through built-in partial function application.
--------------------------------------------------------------------------------
/Sources/PartialOperatorApplication.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PartialOperatorApplication.swift
3 | // PartialOperatorApplication
4 | //
5 | // Created by Michael Pangburn on 2/5/18.
6 | // Copyright © 2018 Michael Pangburn. All rights reserved.
7 | //
8 |
9 | // MARK: - Equatable operators
10 |
11 | prefix operator ==
12 | prefix func == (rhs: T) -> (_ lhs: T) -> Bool {
13 | return { $0 == rhs }
14 | }
15 |
16 | postfix operator ==
17 | postfix func == (lhs: T) -> (_ rhs: T) -> Bool {
18 | return { lhs == $0 }
19 | }
20 |
21 | prefix operator !=
22 | prefix func != (rhs: T) -> (_ lhs: T) -> Bool {
23 | return { $0 != rhs }
24 | }
25 |
26 | /* Postfix operators cannot begin with '!' because of its use with Optionals */
27 | // postfix operator !=
28 | // postfix func != (lhs: T) -> (_ rhs: T) -> Bool {
29 | // return { lhs != $0 }
30 | // }
31 |
32 | prefix operator ~=
33 | prefix func ~= (rhs: T) -> (_ lhs: T) -> Bool {
34 | return { $0 ~= rhs }
35 | }
36 |
37 | postfix operator ~=
38 | postfix func ~= (lhs: T) -> (_ rhs: T) -> Bool {
39 | return { lhs ~= $0 }
40 | }
41 |
42 | // MARK: - Identity equatable operators
43 |
44 | prefix operator ===
45 | prefix func === (rhs: T) -> (_ lhs: T) -> Bool {
46 | return { $0 === rhs }
47 | }
48 |
49 | postfix operator ===
50 | postfix func === (lhs: T) -> (_ rhs: T) -> Bool {
51 | return { lhs === $0 }
52 | }
53 |
54 | prefix operator !==
55 | prefix func !== (rhs: T) -> (_ lhs: T) -> Bool {
56 | return { $0 !== rhs }
57 | }
58 |
59 | /* Postfix operators cannot begin with '!' because of its use with Optionals */
60 | // postfix operator !==
61 | // postfix func !== (lhs: T) -> (_ rhs: T) -> Bool {
62 | // return { lhs !== $0 }
63 | // }
64 |
65 | // MARK: - Comparable operators
66 |
67 | /* Prefix '<' is reserved to avoid compiler confusion in identifying generics */
68 | // prefix operator <
69 | // prefix func < (rhs: T) -> (_ lhs: T) -> Bool {
70 | // return { $0 < rhs }
71 | // }
72 |
73 | postfix operator <
74 | postfix func < (lhs: T) -> (_ rhs: T) -> Bool {
75 | return { lhs < $0 }
76 | }
77 |
78 | prefix operator >
79 | prefix func > (rhs: T) -> (_ lhs: T) -> Bool {
80 | return { $0 > rhs }
81 | }
82 |
83 | /* Postfix '>' is reserved to avoid compiler confusion in identifying generics */
84 | // postfix operator >
85 | // postfix func > (lhs: T) -> (_ rhs: T) -> Bool {
86 | // return { lhs > $0 }
87 | // }
88 |
89 | prefix operator <=
90 | prefix func <= (rhs: T) -> (_ lhs: T) -> Bool {
91 | return { $0 <= rhs }
92 | }
93 |
94 | postfix operator <=
95 | postfix func <= (lhs: T) -> (_ rhs: T) -> Bool {
96 | return { lhs <= $0 }
97 | }
98 |
99 | prefix operator >=
100 | prefix func >= (rhs: T) -> (_ lhs: T) -> Bool {
101 | return { $0 >= rhs }
102 | }
103 |
104 | postfix operator >=
105 | postfix func >= (lhs: T) -> (_ rhs: T) -> Bool {
106 | return { lhs >= $0 }
107 | }
108 |
109 | // MARK: - Numeric operators
110 |
111 | prefix func + (rhs: T) -> (_ lhs: T) -> T {
112 | return { $0 + rhs }
113 | }
114 |
115 | postfix operator +
116 | postfix func + (lhs: T) -> (_ rhs: T) -> T {
117 | return { lhs + $0 }
118 | }
119 |
120 | /* Interestingly, overloading unary '+' works fine, but not unary '-' */
121 | // prefix func - (rhs: T) -> (_ lhs: T) -> T {
122 | // return { $0 - rhs }
123 | // }
124 |
125 | postfix operator -
126 | postfix func - (lhs: T) -> (_ rhs: T) -> T {
127 | return { lhs - $0 }
128 | }
129 |
130 | prefix operator *
131 | prefix func * (rhs: T) -> (_ lhs: T) -> T {
132 | return { $0 * rhs }
133 | }
134 |
135 | postfix operator *
136 | postfix func * (lhs: T) -> (_ rhs: T) -> T {
137 | return { lhs * $0 }
138 | }
139 |
140 | // MARK: - FloatingPoint operators
141 |
142 | prefix operator /
143 | prefix func / (rhs: T) -> (_ lhs: T) -> T {
144 | return { $0 / rhs }
145 | }
146 |
147 | postfix operator /
148 | postfix func / (lhs: T) -> (_ rhs: T) -> T {
149 | return { lhs / $0 }
150 | }
151 |
152 | // MARK: - BinaryInteger operators
153 |
154 | prefix func / (rhs: T) -> (_ lhs: T) -> T {
155 | return { $0 / rhs }
156 | }
157 |
158 | postfix func / (lhs: T) -> (_ rhs: T) -> T {
159 | return { lhs / $0 }
160 | }
161 |
162 | prefix operator %
163 | prefix func % (rhs: T) -> (_ lhs: T) -> T {
164 | return { $0 % rhs }
165 | }
166 |
167 | postfix operator %
168 | postfix func % (lhs: T) -> (_ rhs: T) -> T {
169 | return { lhs % $0 }
170 | }
171 |
172 | /* Prefix '&' is reserved for passing variables as inout parameters */
173 | // prefix operator &
174 | // prefix func & (rhs: T) -> (_ lhs: T) -> T {
175 | // return { $0 & rhs }
176 | // }
177 |
178 | postfix operator &
179 | postfix func & (lhs: T) -> (_ rhs: T) -> T {
180 | return { lhs & $0 }
181 | }
182 |
183 | prefix operator |
184 | prefix func | (rhs: T) -> (_ lhs: T) -> T {
185 | return { $0 | rhs }
186 | }
187 |
188 | postfix operator |
189 | postfix func | (lhs: T) -> (_ rhs: T) -> T {
190 | return { lhs | $0 }
191 | }
192 |
193 | prefix operator ^
194 | prefix func ^ (rhs: T) -> (_ lhs: T) -> T {
195 | return { $0 ^ rhs }
196 | }
197 |
198 | postfix operator ^
199 | postfix func ^ (lhs: T) -> (_ rhs: T) -> T {
200 | return { lhs ^ $0 }
201 | }
202 |
203 | prefix operator <<
204 | prefix func << (rhs: T) -> (_ lhs: T) -> T {
205 | return { $0 << rhs }
206 | }
207 |
208 | postfix operator <<
209 | postfix func << (lhs: T) -> (_ rhs: T) -> T {
210 | return { lhs << $0 }
211 | }
212 |
213 | prefix operator >>
214 | prefix func >> (rhs: T) -> (_ lhs: T) -> T {
215 | return { $0 >> rhs }
216 | }
217 |
218 | postfix operator >>
219 | postfix func >> (lhs: T) -> (_ rhs: T) -> T {
220 | return { lhs >> $0 }
221 | }
222 |
223 | // MARK: - FixedWidthInteger operators
224 |
225 | prefix operator &+
226 | prefix func &+ (rhs: T) -> (_ lhs: T) -> T {
227 | return { $0 &+ rhs }
228 | }
229 |
230 | postfix operator &+
231 | postfix func &+ (lhs: T) -> (_ rhs: T) -> T {
232 | return { lhs &+ $0 }
233 | }
234 |
235 | prefix operator &-
236 | prefix func &- (rhs: T) -> (_ lhs: T) -> T {
237 | return { $0 &- rhs }
238 | }
239 |
240 | postfix operator &-
241 | postfix func &- (lhs: T) -> (_ rhs: T) -> T {
242 | return { lhs &- $0 }
243 | }
244 |
245 | prefix operator &*
246 | prefix func &* (rhs: T) -> (_ lhs: T) -> T {
247 | return { $0 &* rhs }
248 | }
249 |
250 | postfix operator &*
251 | postfix func &* (lhs: T) -> (_ rhs: T) -> T {
252 | return { lhs &* $0 }
253 | }
254 |
255 | prefix operator &<<
256 | prefix func &<< (rhs: T) -> (_ lhs: T) -> T {
257 | return { $0 &<< rhs }
258 | }
259 |
260 | postfix operator &<<
261 | postfix func &<< (lhs: T) -> (_ rhs: T) -> T {
262 | return { lhs &<< $0 }
263 | }
264 |
265 | prefix operator &>>
266 | prefix func &>> (rhs: T) -> (_ lhs: T) -> T {
267 | return { $0 &>> rhs }
268 | }
269 |
270 | postfix operator &>>
271 | postfix func &>> (lhs: T) -> (_ rhs: T) -> T {
272 | return { lhs &>> $0 }
273 | }
274 |
275 | // MARK: - Bool operators
276 |
277 | prefix operator &&
278 | prefix func && (rhs: @escaping @autoclosure () -> Bool) -> (_ lhs: Bool) -> Bool {
279 | return { $0 && rhs() }
280 | }
281 |
282 | postfix operator &&
283 | postfix func && (lhs: Bool) -> (_ rhs: Bool) -> Bool {
284 | return { lhs && $0 }
285 | }
286 |
287 | prefix operator ||
288 | prefix func || (rhs: @escaping @autoclosure () -> Bool) -> (_ lhs: Bool) -> Bool {
289 | return { $0 || rhs() }
290 | }
291 |
292 | postfix operator ||
293 | postfix func || (lhs: Bool) -> (_ rhs: Bool) -> Bool {
294 | return { lhs || $0 }
295 | }
296 |
297 | // MARK: - Optional operators
298 |
299 | prefix operator ??
300 | prefix func ?? (rhs: @escaping @autoclosure () -> T) -> (_ lhs: T?) -> T {
301 | return { $0 ?? rhs() }
302 | }
303 |
304 | /* Postfix operators cannot begin with '?' because of its use with Optionals */
305 | // postfix operator ??
306 | // postfix func ?? (lhs: T?) -> (_ rhs: T) -> T {
307 | // return { lhs ?? $0 }
308 | // }
309 |
310 | // MARK: - Utilities
311 |
312 | func not(_ f: @escaping (T) -> Bool) -> (T) -> Bool {
313 | return { !f($0) }
314 | }
315 |
316 | prefix func ! (f: @escaping (T) -> Bool) -> (T) -> Bool {
317 | return { !f($0) }
318 | }
319 |
320 | // c.f. https://oleb.net/blog/2015/09/swift-pattern-matching/
321 | func ~= (pattern: (T) -> Bool, value: T) -> Bool {
322 | return pattern(value)
323 | }
324 |
325 |
--------------------------------------------------------------------------------
/PartialOperatorApplication.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 48;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 89172A69202985FB00827A8D /* PartialOperatorApplication.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 89172A5F202985FB00827A8D /* PartialOperatorApplication.framework */; };
11 | 89172A6E202985FB00827A8D /* PartialOperatorApplicationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 89172A6D202985FB00827A8D /* PartialOperatorApplicationTests.swift */; };
12 | 89172A70202985FB00827A8D /* PartialOperatorApplication.h in Headers */ = {isa = PBXBuildFile; fileRef = 89172A62202985FB00827A8D /* PartialOperatorApplication.h */; settings = {ATTRIBUTES = (Public, ); }; };
13 | 89172A7B2029861200827A8D /* PartialOperatorApplication.swift in Sources */ = {isa = PBXBuildFile; fileRef = 89172A7A2029861200827A8D /* PartialOperatorApplication.swift */; };
14 | /* End PBXBuildFile section */
15 |
16 | /* Begin PBXContainerItemProxy section */
17 | 89172A6A202985FB00827A8D /* PBXContainerItemProxy */ = {
18 | isa = PBXContainerItemProxy;
19 | containerPortal = 89172A56202985FB00827A8D /* Project object */;
20 | proxyType = 1;
21 | remoteGlobalIDString = 89172A5E202985FB00827A8D;
22 | remoteInfo = PartialOperatorApplication;
23 | };
24 | /* End PBXContainerItemProxy section */
25 |
26 | /* Begin PBXFileReference section */
27 | 89172A5F202985FB00827A8D /* PartialOperatorApplication.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = PartialOperatorApplication.framework; sourceTree = BUILT_PRODUCTS_DIR; };
28 | 89172A62202985FB00827A8D /* PartialOperatorApplication.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PartialOperatorApplication.h; sourceTree = ""; };
29 | 89172A63202985FB00827A8D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
30 | 89172A68202985FB00827A8D /* PartialOperatorApplicationTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = PartialOperatorApplicationTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
31 | 89172A6D202985FB00827A8D /* PartialOperatorApplicationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PartialOperatorApplicationTests.swift; sourceTree = ""; };
32 | 89172A6F202985FB00827A8D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
33 | 89172A7A2029861200827A8D /* PartialOperatorApplication.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PartialOperatorApplication.swift; sourceTree = ""; };
34 | /* End PBXFileReference section */
35 |
36 | /* Begin PBXFrameworksBuildPhase section */
37 | 89172A5B202985FB00827A8D /* Frameworks */ = {
38 | isa = PBXFrameworksBuildPhase;
39 | buildActionMask = 2147483647;
40 | files = (
41 | );
42 | runOnlyForDeploymentPostprocessing = 0;
43 | };
44 | 89172A65202985FB00827A8D /* Frameworks */ = {
45 | isa = PBXFrameworksBuildPhase;
46 | buildActionMask = 2147483647;
47 | files = (
48 | 89172A69202985FB00827A8D /* PartialOperatorApplication.framework in Frameworks */,
49 | );
50 | runOnlyForDeploymentPostprocessing = 0;
51 | };
52 | /* End PBXFrameworksBuildPhase section */
53 |
54 | /* Begin PBXGroup section */
55 | 89172A55202985FB00827A8D = {
56 | isa = PBXGroup;
57 | children = (
58 | 89172A792029860900827A8D /* Sources */,
59 | 89172A61202985FB00827A8D /* PartialOperatorApplication */,
60 | 89172A6C202985FB00827A8D /* PartialOperatorApplicationTests */,
61 | 89172A60202985FB00827A8D /* Products */,
62 | );
63 | sourceTree = "";
64 | };
65 | 89172A60202985FB00827A8D /* Products */ = {
66 | isa = PBXGroup;
67 | children = (
68 | 89172A5F202985FB00827A8D /* PartialOperatorApplication.framework */,
69 | 89172A68202985FB00827A8D /* PartialOperatorApplicationTests.xctest */,
70 | );
71 | name = Products;
72 | sourceTree = "";
73 | };
74 | 89172A61202985FB00827A8D /* PartialOperatorApplication */ = {
75 | isa = PBXGroup;
76 | children = (
77 | 89172A62202985FB00827A8D /* PartialOperatorApplication.h */,
78 | 89172A63202985FB00827A8D /* Info.plist */,
79 | );
80 | path = PartialOperatorApplication;
81 | sourceTree = "";
82 | };
83 | 89172A6C202985FB00827A8D /* PartialOperatorApplicationTests */ = {
84 | isa = PBXGroup;
85 | children = (
86 | 89172A6D202985FB00827A8D /* PartialOperatorApplicationTests.swift */,
87 | 89172A6F202985FB00827A8D /* Info.plist */,
88 | );
89 | path = PartialOperatorApplicationTests;
90 | sourceTree = "";
91 | };
92 | 89172A792029860900827A8D /* Sources */ = {
93 | isa = PBXGroup;
94 | children = (
95 | 89172A7A2029861200827A8D /* PartialOperatorApplication.swift */,
96 | );
97 | path = Sources;
98 | sourceTree = "";
99 | };
100 | /* End PBXGroup section */
101 |
102 | /* Begin PBXHeadersBuildPhase section */
103 | 89172A5C202985FB00827A8D /* Headers */ = {
104 | isa = PBXHeadersBuildPhase;
105 | buildActionMask = 2147483647;
106 | files = (
107 | 89172A70202985FB00827A8D /* PartialOperatorApplication.h in Headers */,
108 | );
109 | runOnlyForDeploymentPostprocessing = 0;
110 | };
111 | /* End PBXHeadersBuildPhase section */
112 |
113 | /* Begin PBXNativeTarget section */
114 | 89172A5E202985FB00827A8D /* PartialOperatorApplication */ = {
115 | isa = PBXNativeTarget;
116 | buildConfigurationList = 89172A73202985FB00827A8D /* Build configuration list for PBXNativeTarget "PartialOperatorApplication" */;
117 | buildPhases = (
118 | 89172A5A202985FB00827A8D /* Sources */,
119 | 89172A5B202985FB00827A8D /* Frameworks */,
120 | 89172A5C202985FB00827A8D /* Headers */,
121 | 89172A5D202985FB00827A8D /* Resources */,
122 | );
123 | buildRules = (
124 | );
125 | dependencies = (
126 | );
127 | name = PartialOperatorApplication;
128 | productName = PartialOperatorApplication;
129 | productReference = 89172A5F202985FB00827A8D /* PartialOperatorApplication.framework */;
130 | productType = "com.apple.product-type.framework";
131 | };
132 | 89172A67202985FB00827A8D /* PartialOperatorApplicationTests */ = {
133 | isa = PBXNativeTarget;
134 | buildConfigurationList = 89172A76202985FB00827A8D /* Build configuration list for PBXNativeTarget "PartialOperatorApplicationTests" */;
135 | buildPhases = (
136 | 89172A64202985FB00827A8D /* Sources */,
137 | 89172A65202985FB00827A8D /* Frameworks */,
138 | 89172A66202985FB00827A8D /* Resources */,
139 | );
140 | buildRules = (
141 | );
142 | dependencies = (
143 | 89172A6B202985FB00827A8D /* PBXTargetDependency */,
144 | );
145 | name = PartialOperatorApplicationTests;
146 | productName = PartialOperatorApplicationTests;
147 | productReference = 89172A68202985FB00827A8D /* PartialOperatorApplicationTests.xctest */;
148 | productType = "com.apple.product-type.bundle.unit-test";
149 | };
150 | /* End PBXNativeTarget section */
151 |
152 | /* Begin PBXProject section */
153 | 89172A56202985FB00827A8D /* Project object */ = {
154 | isa = PBXProject;
155 | attributes = {
156 | LastSwiftUpdateCheck = 0920;
157 | LastUpgradeCheck = 0920;
158 | ORGANIZATIONNAME = "Michael Pangburn";
159 | TargetAttributes = {
160 | 89172A5E202985FB00827A8D = {
161 | CreatedOnToolsVersion = 9.2;
162 | LastSwiftMigration = 0920;
163 | ProvisioningStyle = Automatic;
164 | };
165 | 89172A67202985FB00827A8D = {
166 | CreatedOnToolsVersion = 9.2;
167 | ProvisioningStyle = Automatic;
168 | };
169 | };
170 | };
171 | buildConfigurationList = 89172A59202985FB00827A8D /* Build configuration list for PBXProject "PartialOperatorApplication" */;
172 | compatibilityVersion = "Xcode 8.0";
173 | developmentRegion = en;
174 | hasScannedForEncodings = 0;
175 | knownRegions = (
176 | en,
177 | );
178 | mainGroup = 89172A55202985FB00827A8D;
179 | productRefGroup = 89172A60202985FB00827A8D /* Products */;
180 | projectDirPath = "";
181 | projectRoot = "";
182 | targets = (
183 | 89172A5E202985FB00827A8D /* PartialOperatorApplication */,
184 | 89172A67202985FB00827A8D /* PartialOperatorApplicationTests */,
185 | );
186 | };
187 | /* End PBXProject section */
188 |
189 | /* Begin PBXResourcesBuildPhase section */
190 | 89172A5D202985FB00827A8D /* Resources */ = {
191 | isa = PBXResourcesBuildPhase;
192 | buildActionMask = 2147483647;
193 | files = (
194 | );
195 | runOnlyForDeploymentPostprocessing = 0;
196 | };
197 | 89172A66202985FB00827A8D /* Resources */ = {
198 | isa = PBXResourcesBuildPhase;
199 | buildActionMask = 2147483647;
200 | files = (
201 | );
202 | runOnlyForDeploymentPostprocessing = 0;
203 | };
204 | /* End PBXResourcesBuildPhase section */
205 |
206 | /* Begin PBXSourcesBuildPhase section */
207 | 89172A5A202985FB00827A8D /* Sources */ = {
208 | isa = PBXSourcesBuildPhase;
209 | buildActionMask = 2147483647;
210 | files = (
211 | 89172A7B2029861200827A8D /* PartialOperatorApplication.swift in Sources */,
212 | );
213 | runOnlyForDeploymentPostprocessing = 0;
214 | };
215 | 89172A64202985FB00827A8D /* Sources */ = {
216 | isa = PBXSourcesBuildPhase;
217 | buildActionMask = 2147483647;
218 | files = (
219 | 89172A6E202985FB00827A8D /* PartialOperatorApplicationTests.swift in Sources */,
220 | );
221 | runOnlyForDeploymentPostprocessing = 0;
222 | };
223 | /* End PBXSourcesBuildPhase section */
224 |
225 | /* Begin PBXTargetDependency section */
226 | 89172A6B202985FB00827A8D /* PBXTargetDependency */ = {
227 | isa = PBXTargetDependency;
228 | target = 89172A5E202985FB00827A8D /* PartialOperatorApplication */;
229 | targetProxy = 89172A6A202985FB00827A8D /* PBXContainerItemProxy */;
230 | };
231 | /* End PBXTargetDependency section */
232 |
233 | /* Begin XCBuildConfiguration section */
234 | 89172A71202985FB00827A8D /* Debug */ = {
235 | isa = XCBuildConfiguration;
236 | buildSettings = {
237 | ALWAYS_SEARCH_USER_PATHS = NO;
238 | CLANG_ANALYZER_NONNULL = YES;
239 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
240 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
241 | CLANG_CXX_LIBRARY = "libc++";
242 | CLANG_ENABLE_MODULES = YES;
243 | CLANG_ENABLE_OBJC_ARC = YES;
244 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
245 | CLANG_WARN_BOOL_CONVERSION = YES;
246 | CLANG_WARN_COMMA = YES;
247 | CLANG_WARN_CONSTANT_CONVERSION = YES;
248 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
249 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
250 | CLANG_WARN_EMPTY_BODY = YES;
251 | CLANG_WARN_ENUM_CONVERSION = YES;
252 | CLANG_WARN_INFINITE_RECURSION = YES;
253 | CLANG_WARN_INT_CONVERSION = YES;
254 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
255 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
256 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
257 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
258 | CLANG_WARN_STRICT_PROTOTYPES = YES;
259 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
260 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
261 | CLANG_WARN_UNREACHABLE_CODE = YES;
262 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
263 | CODE_SIGN_IDENTITY = "iPhone Developer";
264 | COPY_PHASE_STRIP = NO;
265 | CURRENT_PROJECT_VERSION = 1;
266 | DEBUG_INFORMATION_FORMAT = dwarf;
267 | ENABLE_STRICT_OBJC_MSGSEND = YES;
268 | ENABLE_TESTABILITY = YES;
269 | GCC_C_LANGUAGE_STANDARD = gnu11;
270 | GCC_DYNAMIC_NO_PIC = NO;
271 | GCC_NO_COMMON_BLOCKS = YES;
272 | GCC_OPTIMIZATION_LEVEL = 0;
273 | GCC_PREPROCESSOR_DEFINITIONS = (
274 | "DEBUG=1",
275 | "$(inherited)",
276 | );
277 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
278 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
279 | GCC_WARN_UNDECLARED_SELECTOR = YES;
280 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
281 | GCC_WARN_UNUSED_FUNCTION = YES;
282 | GCC_WARN_UNUSED_VARIABLE = YES;
283 | IPHONEOS_DEPLOYMENT_TARGET = 11.2;
284 | MTL_ENABLE_DEBUG_INFO = YES;
285 | ONLY_ACTIVE_ARCH = YES;
286 | SDKROOT = iphoneos;
287 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
288 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
289 | VERSIONING_SYSTEM = "apple-generic";
290 | VERSION_INFO_PREFIX = "";
291 | };
292 | name = Debug;
293 | };
294 | 89172A72202985FB00827A8D /* Release */ = {
295 | isa = XCBuildConfiguration;
296 | buildSettings = {
297 | ALWAYS_SEARCH_USER_PATHS = NO;
298 | CLANG_ANALYZER_NONNULL = YES;
299 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
300 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
301 | CLANG_CXX_LIBRARY = "libc++";
302 | CLANG_ENABLE_MODULES = YES;
303 | CLANG_ENABLE_OBJC_ARC = YES;
304 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
305 | CLANG_WARN_BOOL_CONVERSION = YES;
306 | CLANG_WARN_COMMA = YES;
307 | CLANG_WARN_CONSTANT_CONVERSION = YES;
308 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
309 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
310 | CLANG_WARN_EMPTY_BODY = YES;
311 | CLANG_WARN_ENUM_CONVERSION = YES;
312 | CLANG_WARN_INFINITE_RECURSION = YES;
313 | CLANG_WARN_INT_CONVERSION = YES;
314 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
315 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
316 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
317 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
318 | CLANG_WARN_STRICT_PROTOTYPES = YES;
319 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
320 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
321 | CLANG_WARN_UNREACHABLE_CODE = YES;
322 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
323 | CODE_SIGN_IDENTITY = "iPhone Developer";
324 | COPY_PHASE_STRIP = NO;
325 | CURRENT_PROJECT_VERSION = 1;
326 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
327 | ENABLE_NS_ASSERTIONS = NO;
328 | ENABLE_STRICT_OBJC_MSGSEND = YES;
329 | GCC_C_LANGUAGE_STANDARD = gnu11;
330 | GCC_NO_COMMON_BLOCKS = YES;
331 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
332 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
333 | GCC_WARN_UNDECLARED_SELECTOR = YES;
334 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
335 | GCC_WARN_UNUSED_FUNCTION = YES;
336 | GCC_WARN_UNUSED_VARIABLE = YES;
337 | IPHONEOS_DEPLOYMENT_TARGET = 11.2;
338 | MTL_ENABLE_DEBUG_INFO = NO;
339 | SDKROOT = iphoneos;
340 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
341 | VALIDATE_PRODUCT = YES;
342 | VERSIONING_SYSTEM = "apple-generic";
343 | VERSION_INFO_PREFIX = "";
344 | };
345 | name = Release;
346 | };
347 | 89172A74202985FB00827A8D /* Debug */ = {
348 | isa = XCBuildConfiguration;
349 | buildSettings = {
350 | CLANG_ENABLE_MODULES = YES;
351 | CODE_SIGN_IDENTITY = "";
352 | CODE_SIGN_STYLE = Automatic;
353 | DEFINES_MODULE = YES;
354 | DEVELOPMENT_TEAM = 5Q5Q8W9ATZ;
355 | DYLIB_COMPATIBILITY_VERSION = 1;
356 | DYLIB_CURRENT_VERSION = 1;
357 | DYLIB_INSTALL_NAME_BASE = "@rpath";
358 | INFOPLIST_FILE = PartialOperatorApplication/Info.plist;
359 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
360 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
361 | PRODUCT_BUNDLE_IDENTIFIER = com.mpangburn.PartialOperatorApplication;
362 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
363 | SKIP_INSTALL = YES;
364 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
365 | SWIFT_VERSION = 4.0;
366 | TARGETED_DEVICE_FAMILY = "1,2";
367 | };
368 | name = Debug;
369 | };
370 | 89172A75202985FB00827A8D /* Release */ = {
371 | isa = XCBuildConfiguration;
372 | buildSettings = {
373 | CLANG_ENABLE_MODULES = YES;
374 | CODE_SIGN_IDENTITY = "";
375 | CODE_SIGN_STYLE = Automatic;
376 | DEFINES_MODULE = YES;
377 | DEVELOPMENT_TEAM = 5Q5Q8W9ATZ;
378 | DYLIB_COMPATIBILITY_VERSION = 1;
379 | DYLIB_CURRENT_VERSION = 1;
380 | DYLIB_INSTALL_NAME_BASE = "@rpath";
381 | INFOPLIST_FILE = PartialOperatorApplication/Info.plist;
382 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
383 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
384 | PRODUCT_BUNDLE_IDENTIFIER = com.mpangburn.PartialOperatorApplication;
385 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
386 | SKIP_INSTALL = YES;
387 | SWIFT_VERSION = 4.0;
388 | TARGETED_DEVICE_FAMILY = "1,2";
389 | };
390 | name = Release;
391 | };
392 | 89172A77202985FB00827A8D /* Debug */ = {
393 | isa = XCBuildConfiguration;
394 | buildSettings = {
395 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
396 | CODE_SIGN_STYLE = Automatic;
397 | DEVELOPMENT_TEAM = 5Q5Q8W9ATZ;
398 | INFOPLIST_FILE = PartialOperatorApplicationTests/Info.plist;
399 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
400 | PRODUCT_BUNDLE_IDENTIFIER = com.mpangburn.PartialOperatorApplicationTests;
401 | PRODUCT_NAME = "$(TARGET_NAME)";
402 | SWIFT_VERSION = 4.0;
403 | TARGETED_DEVICE_FAMILY = "1,2";
404 | };
405 | name = Debug;
406 | };
407 | 89172A78202985FB00827A8D /* Release */ = {
408 | isa = XCBuildConfiguration;
409 | buildSettings = {
410 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
411 | CODE_SIGN_STYLE = Automatic;
412 | DEVELOPMENT_TEAM = 5Q5Q8W9ATZ;
413 | INFOPLIST_FILE = PartialOperatorApplicationTests/Info.plist;
414 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
415 | PRODUCT_BUNDLE_IDENTIFIER = com.mpangburn.PartialOperatorApplicationTests;
416 | PRODUCT_NAME = "$(TARGET_NAME)";
417 | SWIFT_VERSION = 4.0;
418 | TARGETED_DEVICE_FAMILY = "1,2";
419 | };
420 | name = Release;
421 | };
422 | /* End XCBuildConfiguration section */
423 |
424 | /* Begin XCConfigurationList section */
425 | 89172A59202985FB00827A8D /* Build configuration list for PBXProject "PartialOperatorApplication" */ = {
426 | isa = XCConfigurationList;
427 | buildConfigurations = (
428 | 89172A71202985FB00827A8D /* Debug */,
429 | 89172A72202985FB00827A8D /* Release */,
430 | );
431 | defaultConfigurationIsVisible = 0;
432 | defaultConfigurationName = Release;
433 | };
434 | 89172A73202985FB00827A8D /* Build configuration list for PBXNativeTarget "PartialOperatorApplication" */ = {
435 | isa = XCConfigurationList;
436 | buildConfigurations = (
437 | 89172A74202985FB00827A8D /* Debug */,
438 | 89172A75202985FB00827A8D /* Release */,
439 | );
440 | defaultConfigurationIsVisible = 0;
441 | defaultConfigurationName = Release;
442 | };
443 | 89172A76202985FB00827A8D /* Build configuration list for PBXNativeTarget "PartialOperatorApplicationTests" */ = {
444 | isa = XCConfigurationList;
445 | buildConfigurations = (
446 | 89172A77202985FB00827A8D /* Debug */,
447 | 89172A78202985FB00827A8D /* Release */,
448 | );
449 | defaultConfigurationIsVisible = 0;
450 | defaultConfigurationName = Release;
451 | };
452 | /* End XCConfigurationList section */
453 | };
454 | rootObject = 89172A56202985FB00827A8D /* Project object */;
455 | }
456 |
--------------------------------------------------------------------------------