diff --git a/Fission.xcodeproj/project.pbxproj b/Fission.xcodeproj/project.pbxproj index 8485453..d0d6d3a 100644 --- a/Fission.xcodeproj/project.pbxproj +++ b/Fission.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + B92E5B111DEA3D04008F5F32 /* PrcendenceGroups.swift in Sources */ = {isa = PBXBuildFile; fileRef = B92E5B101DEA3D04008F5F32 /* PrcendenceGroups.swift */; }; B98C47AF1C21248B003F157C /* CollectionType.swift in Sources */ = {isa = PBXBuildFile; fileRef = B98C47A71C21248B003F157C /* CollectionType.swift */; }; B98C47B01C21248B003F157C /* CollectionType.swift in Sources */ = {isa = PBXBuildFile; fileRef = B98C47A71C21248B003F157C /* CollectionType.swift */; }; B98C47B11C21248B003F157C /* Curry.swift in Sources */ = {isa = PBXBuildFile; fileRef = B98C47A81C21248B003F157C /* Curry.swift */; }; @@ -40,6 +41,7 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ + B92E5B101DEA3D04008F5F32 /* PrcendenceGroups.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PrcendenceGroups.swift; sourceTree = ""; }; B93D3C4B1C1FD5F200557F6F /* Fission.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Fission.framework; sourceTree = BUILT_PRODUCTS_DIR; }; B93D3C7E1C20F42D00557F6F /* Fission.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Fission.framework; sourceTree = BUILT_PRODUCTS_DIR; }; B98C47A71C21248B003F157C /* CollectionType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CollectionType.swift; sourceTree = ""; }; @@ -112,6 +114,7 @@ B98C47AA1C21248B003F157C /* FunctionComposition.swift */, B98C47AB1C21248B003F157C /* Mutation.swift */, B98C47AC1C21248B003F157C /* Operators.swift */, + B92E5B101DEA3D04008F5F32 /* PrcendenceGroups.swift */, B98C47AD1C21248B003F157C /* Optional.swift */, B98C47AE1C21248B003F157C /* SequenceType.swift */, ); @@ -224,12 +227,14 @@ TargetAttributes = { B93D3C4A1C1FD5F200557F6F = { CreatedOnToolsVersion = 7.2; + LastSwiftMigration = 0810; }; B93D3C7D1C20F42D00557F6F = { CreatedOnToolsVersion = 7.2; }; B9E527781C211B8E00011F20 = { CreatedOnToolsVersion = 7.2; + LastSwiftMigration = 0810; }; }; }; @@ -283,6 +288,7 @@ files = ( B98C47BD1C21248B003F157C /* SequenceType.swift in Sources */, B98C47B31C21248B003F157C /* FunctionApplication.swift in Sources */, + B92E5B111DEA3D04008F5F32 /* PrcendenceGroups.swift in Sources */, B98C47AF1C21248B003F157C /* CollectionType.swift in Sources */, B98C47B51C21248B003F157C /* FunctionComposition.swift in Sources */, B98C47BB1C21248B003F157C /* Optional.swift in Sources */, @@ -429,6 +435,7 @@ PRODUCT_NAME = Fission; SKIP_INSTALL = YES; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 3.0; }; name = Debug; }; @@ -448,6 +455,7 @@ PRODUCT_BUNDLE_IDENTIFIER = pear.Fission; PRODUCT_NAME = Fission; SKIP_INSTALL = YES; + SWIFT_VERSION = 3.0; }; name = Release; }; @@ -500,6 +508,7 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = pear.FissionMacTests; PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; }; name = Debug; }; @@ -511,6 +520,7 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = pear.FissionMacTests; PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; }; name = Release; }; diff --git a/Fission/CollectionType.swift b/Fission/CollectionType.swift index a97245f..fdb67b2 100644 --- a/Fission/CollectionType.swift +++ b/Fission/CollectionType.swift @@ -6,16 +6,16 @@ // Copyright © 2015 Kenneth Ackerson. All rights reserved. // -public extension CollectionType { - public func apply (transforms: [Self.Generator.Element -> T]) -> [T] { +public extension Collection { + public func apply (_ transforms: [(Self.Iterator.Element) -> T]) -> [T] { return transforms.flatMap { return self.map($0) } } } -public func <*> (transforms: [U.Generator.Element -> T], collection: U) -> [T] { +public func <*> (transforms: [(U.Iterator.Element) -> T], collection: U) -> [T] { return collection.apply <| transforms } -public func <^> (@noescape transform: T throws -> U, collection: C) rethrows -> [U] { +public func <^> (transform: (T) throws -> U, collection: C) rethrows -> [U] where C.Iterator.Element == T { return try collection.map(transform) } diff --git a/Fission/Curry.swift b/Fission/Curry.swift index 7380b59..a48131c 100644 --- a/Fission/Curry.swift +++ b/Fission/Curry.swift @@ -13,7 +13,7 @@ Transforms a function with two arguments into two functions with one argument ea - returns: A curried version of the provided function. */ -public func curry (f: (T, U) -> V) -> T -> U -> V { +public func curry (_ f: @escaping (T, U) -> V) -> (T) -> (U) -> V { return { x in return { return f <| (x, $0) @@ -28,7 +28,7 @@ public func curry (f: (T, U) -> V) -> T -> U -> V { - returns: An uncurried version of the provided function. */ -public func uncurry (f: T -> U -> V) -> (T, U) -> V { +public func uncurry (_ f: @escaping (T) -> (U) -> V) -> (T, U) -> V { return { return f <| $0 <| $1 } diff --git a/Fission/FunctionApplication.swift b/Fission/FunctionApplication.swift index 249a3ed..ce34d37 100644 --- a/Fission/FunctionApplication.swift +++ b/Fission/FunctionApplication.swift @@ -6,10 +6,10 @@ // Copyright © 2015 Kenneth Ackerson. All rights reserved. // -public func |> (lhs: T, @noescape transform: T -> U) -> U { +public func |> (lhs: T, transform: (T) -> U) -> U { return transform(lhs) } -public func <| (@noescape transform: T -> U, rhs: T) -> U { +public func <| (transform: (T) -> U, rhs: T) -> U { return transform(rhs) } diff --git a/Fission/FunctionComposition.swift b/Fission/FunctionComposition.swift index edcbacd..909bfc1 100644 --- a/Fission/FunctionComposition.swift +++ b/Fission/FunctionComposition.swift @@ -7,28 +7,28 @@ // /** -Function composostion operator. +Function composition operator. - parameter lhs: The function on the left hand side of this operator. First function to be composed. - parameter rhs: The function on the right hand side of this operator. Second function to be composed. - returns: A function that transforms the first argument of the first function into the return value of the second function. */ -public func >>> (lhs: T -> U, rhs: U -> V) -> T -> V { +public func >>> (lhs: @escaping (T) -> U, rhs: @escaping (U) -> V) -> (T) -> V { return { return $0 |> lhs |> rhs } } /** - Function composostion operator. + Function composition operator. - parameter lhs: The function on the left hand side of this operator. First function to be composed. - parameter rhs: The function on the right hand side of this operator. Second function to be composed. - returns: A function that transforms the first argument of the first function into the return value of the second function. */ -public func <<< (lhs: U -> V, rhs: T -> U) -> T -> V { +public func <<< (lhs: @escaping (U) -> V, rhs: @escaping (T) -> U) -> (T) -> V { return { return $0 |> rhs |> lhs } diff --git a/Fission/Mutation.swift b/Fission/Mutation.swift index 5c650eb..5ec3c39 100644 --- a/Fission/Mutation.swift +++ b/Fission/Mutation.swift @@ -7,7 +7,7 @@ // /// Based on https://twitter.com/jckarter/status/675445367542968320 -public func apply (transform: inout T -> U -> ()) -> T -> U -> T { +public func apply (_ transform: @escaping (inout T) -> (U) -> ()) -> (T) -> (U) -> T { return { a in { b in var mutable = a @@ -30,6 +30,6 @@ public func apply (transform: inout T -> U -> ()) -> T -> U -> T { - returns: A function that returns a function that can tranform `U` to `T`. */ -public func <-> (f: inout T -> U -> (), t: T) -> U -> T { +public func <-> (f: @escaping (inout T) -> (U) -> (), t: T) -> (U) -> T { return t |> (apply <| f) } diff --git a/Fission/Operators.swift b/Fission/Operators.swift index 0354281..25290d8 100644 --- a/Fission/Operators.swift +++ b/Fission/Operators.swift @@ -6,47 +6,20 @@ // Copyright © 2015 Kenneth Ackerson. All rights reserved. // -infix operator <^> { - associativity left - precedence 130 -} - -infix operator <-> { - associativity right - precedence 170 -} - -infix operator <*> { - associativity left - precedence 130 -} - -infix operator -<< { - associativity right - precedence 110 -} - -infix operator >>- { - associativity left - precedence 110 -} - -infix operator |> { - associativity left - precedence 95 -} - -infix operator <| { - associativity left - precedence 95 -} - -infix operator >>> { - associativity right - precedence 175 -} - -infix operator <<< { - associativity right - precedence 175 -} +infix operator <^> : LeftDefaultMonadicFunctions + +infix operator <-> : RightDefaultMonadicFunctions + +infix operator <*> : LeftDefaultMonadicFunctions + +infix operator -<< : RightDefaultMonadicFunctions + +infix operator >>- : LeftDefaultMonadicFunctions + +infix operator |> : ApplicationLeft + +infix operator <| : ApplicationRight + +infix operator >>> : RightDefaultMonadicFunctions + +infix operator <<< : RightDefaultMonadicFunctions diff --git a/Fission/Optional.swift b/Fission/Optional.swift index df187e8..bbc4941 100644 --- a/Fission/Optional.swift +++ b/Fission/Optional.swift @@ -16,7 +16,7 @@ - returns: `nil` if `self` is nil, `f(self!)` otherwise. */ -public func >>- (optional: T?, @noescape transform: T throws -> U?) rethrows -> U? { +public func >>- (optional: T?, transform: (T) throws -> U?) rethrows -> U? { return try optional.flatMap(transform) } @@ -30,7 +30,7 @@ public func >>- (optional: T?, @noescape transform: T throws -> U?) rethr - returns: `nil` if `self` is nil, `f(self!)` otherwise. */ -public func -<< (@noescape transform: T throws -> U?, optional: T?) rethrows -> U? { +public func -<< (transform: (T) throws -> U?, optional: T?) rethrows -> U? { return try optional.flatMap(transform) } @@ -44,7 +44,7 @@ public func -<< (@noescape transform: T throws -> U?, optional: T?) rethr - returns: `nil` if `self == nil`. Otherwise, returns `f(self!)`. */ -public func <^> (@noescape transform: T throws -> U, optional: T?) rethrows -> U? { +public func <^> (transform: (T) throws -> U, optional: T?) rethrows -> U? { return try optional.map(transform) } @@ -57,7 +57,7 @@ public extension Optional { - returns: If `self` or the transform function are `nil` this returns `nil`. Returns an optional type `T`. */ - public func apply (transform: (Wrapped -> T)?) -> T? { + public func apply (_ transform: ((Wrapped) -> T)?) -> T? { return transform.flatMap { self.map($0) } @@ -72,6 +72,6 @@ public extension Optional { - returns: If `self` or the transform function are `nil` this returns `nil`. Returns an optional type `U`. */ -public func <*> (transform: (T -> U)?, optional: T?) -> U? { +public func <*> (transform: ((T) -> U)?, optional: T?) -> U? { return optional.apply <| transform } diff --git a/Fission/PrcendenceGroups.swift b/Fission/PrcendenceGroups.swift new file mode 100644 index 0000000..147d5c9 --- /dev/null +++ b/Fission/PrcendenceGroups.swift @@ -0,0 +1,29 @@ +// +// PrcendenceGroups.swift +// Fission +// +// Created by Kenneth Parker Ackerson on 11/26/16. +// Copyright © 2016 Kenneth Ackerson. All rights reserved. +// + +precedencegroup ApplicationRight { + associativity: left + higherThan: AssignmentPrecedence +} + +precedencegroup ApplicationLeft { + associativity: left + higherThan: AssignmentPrecedence +} + +precedencegroup LeftDefaultMonadicFunctions { + associativity: left + higherThan: AssignmentPrecedence + lowerThan: LogicalDisjunctionPrecedence +} + +precedencegroup RightDefaultMonadicFunctions { + associativity: left + higherThan: AssignmentPrecedence + lowerThan: LogicalDisjunctionPrecedence +} diff --git a/Fission/SequenceType.swift b/Fission/SequenceType.swift index 5f10c71..f62bc9d 100644 --- a/Fission/SequenceType.swift +++ b/Fission/SequenceType.swift @@ -6,7 +6,7 @@ // Copyright © 2015 Kenneth Ackerson. All rights reserved. // -public func >>- (sequence: U, transform: T throws -> S) rethrows -> [S.Generator.Element] { +public func >>- (sequence: U, transform: (T) throws -> S) rethrows -> [S.Iterator.Element] where U.Iterator.Element == T { return try sequence.flatMap(transform) } @@ -17,10 +17,10 @@ public func >>- (sequence: U) -> [T] { +public func compact (_ sequence: U) -> [T] where U.Iterator.Element == T? { return sequence.flatMap { return $0 } } -public func -<< (transform: T throws -> S, sequence: U) rethrows -> [S.Generator.Element] { +public func -<< (transform: (T) throws -> S, sequence: U) rethrows -> [S.Iterator.Element] where U.Iterator.Element == T { return try sequence.flatMap(transform) } diff --git a/FissionMacTests/FissionMacTests.swift b/FissionMacTests/FissionMacTests.swift index e8e17e8..2dd6f1c 100644 --- a/FissionMacTests/FissionMacTests.swift +++ b/FissionMacTests/FissionMacTests.swift @@ -14,7 +14,7 @@ final class FissionMacTests: XCTestCase { func testMap() { let array = ["1", "2"] - func function(string: String) -> Int? { + func function(_ string: String) -> Int? { return Int(string) } @@ -29,7 +29,7 @@ final class FissionMacTests: XCTestCase { let array = ["1", "2"] - func function(string: String) -> [String] { + func function(_ string: String) -> [String] { return [string] } @@ -41,7 +41,7 @@ final class FissionMacTests: XCTestCase { } func testFunctionApplication() { - func function(string: String) -> Int { + func function(_ string: String) -> Int { return 22 } @@ -49,8 +49,21 @@ final class FissionMacTests: XCTestCase { XCTAssert(result == 22) } + func testMultipleFunctionApplication() { + func function(_ string: String) -> Int { + return 22 + } + + func otherFunction(integer: Int) -> Int { + return integer + 5 + } + + let result = "hello" |> function |> otherFunction + XCTAssert(result == 27) + } + func testFunctionApplicationTwo() { - func function(string: String) -> Int { + func function(_ string: String) -> Int { return 22 } @@ -59,21 +72,21 @@ final class FissionMacTests: XCTestCase { } func testFunctionComposition() { - func timesThree(amount: Int) -> Int { + func timesThree(_ amount: Int) -> Int { return amount * 3 } - func count(string: String) -> Int { + func count(_ string: String) -> Int { return string.characters.count } - let m = count >>> timesThree >>> { return [$0] } >>> { return $0.reduce(0, combine: +) } + let m = count >>> timesThree >>> { return [$0] } >>> { return $0.reduce(0, +) } XCTAssert(m("hi") == 6) } func testCompact() { - let array = ["it", Optional.None, "me"] + let array = ["it", Optional.none, "me"] let compacted = array |> compact XCTAssert(compacted.count == 2) }