Skip to content

Commit

Permalink
Clarify specs by defining • as the composition operator
Browse files Browse the repository at this point in the history
  • Loading branch information
sharplet authored and gfontenot committed Dec 15, 2015
1 parent 29488bc commit 17a96db
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 18 deletions.
12 changes: 10 additions & 2 deletions Runes.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@
51DE8A2C1BAB373100124320 /* Functions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8624C5C1A647E6F00C883B3 /* Functions.swift */; };
51DE8A2D1BAB373100124320 /* OptionalSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8624C371A645B0700C883B3 /* OptionalSpec.swift */; };
51DE8A2E1BAB373100124320 /* ArraySpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8624C5F1A647EE400C883B3 /* ArraySpec.swift */; };
CE3407811C0E9F0A00C84170 /* Operators.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE3407801C0E9F0A00C84170 /* Operators.swift */; };
CE3407821C0E9F0A00C84170 /* Operators.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE3407801C0E9F0A00C84170 /* Operators.swift */; };
CE3407831C0E9F0A00C84170 /* Operators.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE3407801C0E9F0A00C84170 /* Operators.swift */; };
EAA6A5181B2F163B0058E9A8 /* Array.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A8C7DE71A5F58330050914C /* Array.swift */; };
EAA6A5191B2F163B0058E9A8 /* Runes.swift in Sources */ = {isa = PBXBuildFile; fileRef = F802D4EE1A5F2341005E236C /* Runes.swift */; };
EAA6A51A1B2F163B0058E9A8 /* Optional.swift in Sources */ = {isa = PBXBuildFile; fileRef = F802D4F01A5F23BE005E236C /* Optional.swift */; };
Expand All @@ -35,8 +38,8 @@
F86B2E241A5F2B9E00C3B8BD /* Runes.h in Headers */ = {isa = PBXBuildFile; fileRef = F802D4D71A5F218E005E236C /* Runes.h */; settings = {ATTRIBUTES = (Public, ); }; };
F86B2E251A5F2BA400C3B8BD /* Runes.swift in Sources */ = {isa = PBXBuildFile; fileRef = F802D4EE1A5F2341005E236C /* Runes.swift */; };
F86B2E261A5F2BA400C3B8BD /* Optional.swift in Sources */ = {isa = PBXBuildFile; fileRef = F802D4F01A5F23BE005E236C /* Optional.swift */; };
F88DE9731BA3854E00A9D383 /* SwiftCheck.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F88DE9721BA3854E00A9D383 /* SwiftCheck.framework */; settings = {ASSET_TAGS = (); }; };
F88DE9751BA3855600A9D383 /* SwiftCheck.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F88DE9741BA3855600A9D383 /* SwiftCheck.framework */; settings = {ASSET_TAGS = (); }; };
F88DE9731BA3854E00A9D383 /* SwiftCheck.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F88DE9721BA3854E00A9D383 /* SwiftCheck.framework */; };
F88DE9751BA3855600A9D383 /* SwiftCheck.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F88DE9741BA3855600A9D383 /* SwiftCheck.framework */; };
F89776E51BA601D500EE823E /* SwiftCheck.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = F88DE9741BA3855600A9D383 /* SwiftCheck.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
F89776E61BA601DE00EE823E /* SwiftCheck.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = F88DE9721BA3854E00A9D383 /* SwiftCheck.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
/* End PBXBuildFile section */
Expand Down Expand Up @@ -92,6 +95,7 @@
4A8C7DE71A5F58330050914C /* Array.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Array.swift; sourceTree = "<group>"; };
51DE8A121BAB363500124320 /* Runes.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Runes.framework; sourceTree = BUILT_PRODUCTS_DIR; };
51DE8A211BAB36E600124320 /* Runes-tvOS Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Runes-tvOS Tests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
CE3407801C0E9F0A00C84170 /* Operators.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Operators.swift; sourceTree = "<group>"; };
EAA6A5101B2F154D0058E9A8 /* Runes.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Runes.framework; sourceTree = BUILT_PRODUCTS_DIR; };
F802D4D21A5F218E005E236C /* Runes.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Runes.framework; sourceTree = BUILT_PRODUCTS_DIR; };
F802D4D61A5F218E005E236C /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
Expand Down Expand Up @@ -267,6 +271,7 @@
isa = PBXGroup;
children = (
F8624C5C1A647E6F00C883B3 /* Functions.swift */,
CE3407801C0E9F0A00C84170 /* Operators.swift */,
);
path = Helpers;
sourceTree = "<group>";
Expand Down Expand Up @@ -561,6 +566,7 @@
buildActionMask = 2147483647;
files = (
51DE8A2D1BAB373100124320 /* OptionalSpec.swift in Sources */,
CE3407831C0E9F0A00C84170 /* Operators.swift in Sources */,
51DE8A2C1BAB373100124320 /* Functions.swift in Sources */,
51DE8A2E1BAB373100124320 /* ArraySpec.swift in Sources */,
);
Expand Down Expand Up @@ -591,6 +597,7 @@
buildActionMask = 2147483647;
files = (
F8624C381A645B0700C883B3 /* OptionalSpec.swift in Sources */,
CE3407811C0E9F0A00C84170 /* Operators.swift in Sources */,
F8624C5E1A647E7300C883B3 /* Functions.swift in Sources */,
F8624C601A647EE400C883B3 /* ArraySpec.swift in Sources */,
);
Expand All @@ -601,6 +608,7 @@
buildActionMask = 2147483647;
files = (
F8624C511A645CB900C883B3 /* OptionalSpec.swift in Sources */,
CE3407821C0E9F0A00C84170 /* Operators.swift in Sources */,
F8624C5D1A647E6F00C883B3 /* Functions.swift in Sources */,
F8624C611A647FB300C883B3 /* ArraySpec.swift in Sources */,
);
Expand Down
4 changes: 0 additions & 4 deletions Tests/Helpers/Functions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,6 @@ func id<A>(a: A) -> A {
return a
}

func compose<A, B, C>(f: B -> C, _ g: A -> B) -> A -> C {
return { x in f(g(x)) }
}

func curry<A, B, C>(f: (A, B) -> C) -> A -> B -> C {
return { a in { b in f(a, b) }}
}
8 changes: 8 additions & 0 deletions Tests/Helpers/Operators.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
infix operator {
associativity right
precedence 170
}

func <A, B, C> (f: B -> C, g: A -> B) -> A -> C {
return { x in f(g(x)) }
}
12 changes: 6 additions & 6 deletions Tests/Tests/ArraySpec.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ class ArraySpec: XCTestCase {
let f = fa.getArrow
let g = fb.getArrow

let lhs = compose(f, g) <^> xs
let rhs = compose(curry(<^>)(f), curry(<^>)(g))(xs)
let lhs = f g <^> xs
let rhs = (curry(<^>)(f) curry(<^>)(g))(xs)

return lhs == rhs
}
Expand Down Expand Up @@ -61,7 +61,7 @@ class ArraySpec: XCTestCase {
let g = fb.getArray.map { $0.getArrow }

let lhs = f <*> (g <*> x)
let rhs = pure(curry(compose)) <*> f <*> g <*> x
let rhs = pure(curry()) <*> f <*> g <*> x

return lhs == rhs
}
Expand All @@ -70,7 +70,7 @@ class ArraySpec: XCTestCase {
func testMonad() {
// return x >>= f = f x
property("left identity law") <- forAll { (x: Int, fa: ArrowOf<Int, Int>) in
let f: Int -> [Int] = compose(pure, fa.getArrow)
let f: Int -> [Int] = pure fa.getArrow

let lhs = pure(x) >>- f
let rhs = f(x)
Expand All @@ -89,8 +89,8 @@ class ArraySpec: XCTestCase {
// (m >>= f) >>= g = m >>= (\x -> f x >>= g)
property("associativity law") <- forAll { (a: ArrayOf<Int>, fa: ArrowOf<Int, Int>, fb: ArrowOf<Int, Int>) in
let m = a.getArray
let f: Int -> [Int] = compose(pure, fa.getArrow)
let g: Int -> [Int] = compose(pure, fb.getArrow)
let f: Int -> [Int] = pure fa.getArrow
let g: Int -> [Int] = pure fb.getArrow

let lhs = (m >>- f) >>- g
let rhs = m >>- { x in f(x) >>- g }
Expand Down
12 changes: 6 additions & 6 deletions Tests/Tests/OptionalSpec.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ class OptionalSpec: XCTestCase {
let g = fb.getArrow
let x = o.getOptional

let lhs = compose(f, g) <^> x
let rhs = compose(curry(<^>)(f), curry(<^>)(g))(x)
let lhs = f g <^> x
let rhs = (curry(<^>)(f) curry(<^>)(g))(x)

return lhs == rhs
}
Expand Down Expand Up @@ -61,7 +61,7 @@ class OptionalSpec: XCTestCase {
let g = fb.getOptional?.getArrow

let lhs = f <*> (g <*> x)
let rhs = pure(curry(compose)) <*> f <*> g <*> x
let rhs = pure(curry()) <*> f <*> g <*> x

return lhs == rhs
}
Expand All @@ -70,7 +70,7 @@ class OptionalSpec: XCTestCase {
func testMonad() {
// return x >>= f = f x
property("left identity law") <- forAll { (x: Int, fa: ArrowOf<Int, Int>) in
let f: Int -> Int? = compose(pure, fa.getArrow)
let f: Int -> Int? = pure fa.getArrow

let lhs = pure(x) >>- f
let rhs = f(x)
Expand All @@ -91,8 +91,8 @@ class OptionalSpec: XCTestCase {
// (m >>= f) >>= g = m >>= (\x -> f x >>= g)
property("associativity law") <- forAll { (o: OptionalOf<Int>, fa: ArrowOf<Int, Int>, fb: ArrowOf<Int, Int>) in
let m = o.getOptional
let f: Int -> Int? = compose(pure, fa.getArrow)
let g: Int -> Int? = compose(pure, fb.getArrow)
let f: Int -> Int? = pure fa.getArrow
let g: Int -> Int? = pure fb.getArrow

let lhs = (m >>- f) >>- g
let rhs = m >>- { x in f(x) >>- g }
Expand Down

0 comments on commit 17a96db

Please sign in to comment.