From fef4682c4161fb2f581c8156368c8d16811201b2 Mon Sep 17 00:00:00 2001 From: Ivan Zemlyaniy Date: Sat, 16 Mar 2019 17:05:22 +0200 Subject: [PATCH] Updated to Swift version 4.2.1 --- .../Contents.swift | 95 ++++++++++++------- .../contents.xcplayground | 2 +- .../xcshareddata/IDEWorkspaceChecks.plist | 8 ++ .../xcshareddata/WorkspaceSettings.xcsettings | 5 + .../timeline.xctimeline | 28 +++--- 5 files changed, 90 insertions(+), 48 deletions(-) create mode 100644 Functors-Applicatives-Monads-In-Pictures.playground/playground.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist create mode 100644 Functors-Applicatives-Monads-In-Pictures.playground/playground.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings diff --git a/Functors-Applicatives-Monads-In-Pictures.playground/Contents.swift b/Functors-Applicatives-Monads-In-Pictures.playground/Contents.swift index bc61c9b..03f9ce5 100644 --- a/Functors-Applicatives-Monads-In-Pictures.playground/Contents.swift +++ b/Functors-Applicatives-Monads-In-Pictures.playground/Contents.swift @@ -6,8 +6,8 @@ //: Optional is just a type enum MyOptional { - case Some(T) - case None + case some(T) + case none } //: ## Functor @@ -18,60 +18,72 @@ func plusThree(addend: Int) -> Int { return addend + 3 } -Optional.Some(2).map(plusThree) +Optional.some(2).map(plusThree) //: We can use autoclosures and be more succint -Optional.Some(2).map { $0 + 3 } +Optional.some(2).map { $0 + 3 } //: If the optional value is .None, map will return .None (nil) -Optional.None.map { $0 + 3 } +Optional.none.map { $0 + 3 } //: Map implementation might look like this -func myMap(a: T?, f: T -> U) -> U? { +func myMap(a: T?, f: (T) -> U) -> U? { switch a { - case .Some(let x): return f(x) - case .None: return .None + case .some(let x): return f(x) + case .none: return .none } } -myMap(Optional.Some(2), f: { $0 + 3 }) +myMap(a: Optional.some(2), f: { $0 + 3 }) //: We can define an infix operator -infix operator <^> { associativity left } +precedencegroup AlternativePrecedence { + associativity: left + higherThan: LogicalConjunctionPrecedence + lowerThan: ComparisonPrecedence +} + +precedencegroup ApplicativePrecedence { + associativity: left + higherThan: AlternativePrecedence + lowerThan: NilCoalescingPrecedence +} -func <^>(f: T -> U, a: T?) -> U? { +infix operator <^> : ApplicativePrecedence + +func <^>(f: (T) -> U, a: T?) -> U? { return a.map(f) } -plusThree <^> Optional.Some(2) +plusThree <^> Optional.some(2) //: Turns out functions can be mapped as well. Functions are functors too! -typealias IntFunction = Int -> Int +typealias IntFunction = (Int) -> Int -func map(f: IntFunction, _ g: IntFunction) -> IntFunction { +func map(_ f: @escaping IntFunction, _ g: @escaping IntFunction) -> IntFunction { return { x in f(g(x)) } } -let foo = map({ $0 + 2 }, { $0 + 3 }) +let foo = map({ $0 * 2 }, { $0 + 3 }) foo(10) //: ## Applicative extension Optional { - func apply(f: (Wrapped -> U)?) -> U? { + func apply(f: ((Wrapped) -> U)?) -> U? { switch f { - case .Some(let someF): return self.map(someF) - case .None: return .None + case .some(let someF): return self.map(someF) + case .none: return .none } } } extension Array { - func apply(fs: [Element -> U]) -> [U] { + func apply(fs: [(Element) -> U]) -> [U] { var result = [U]() for f in fs { for element in self.map(f) { @@ -82,50 +94,67 @@ extension Array { } } -infix operator <*> { associativity left } +infix operator <*> : ApplicativePrecedence -func <*>(f: (T -> U)?, a: T?) -> U? { - return a.apply(f) +func <*>(f: ((T) -> U)?, a: T?) -> U? { + return a.apply(f: f) } -func <*>(f: [T -> U], a: [T]) -> [U] { - return a.apply(f) +func <*>(_ f: [(T) -> U], a: [T]) -> [U] { + return a.apply(fs: f) } -Optional.Some({ $0 + 3 }) <*> Optional.Some(2) +Optional.some({ $0 + 3 }) <*> Optional.some(2) let arrayApplicative = [ { $0 + 3 }, { $0 * 2 } ] <*> [1, 2, 3] //: _Playground (as of Xcode 7 Beta 3) doesn't seem to be happy show the result of array applications , so we'll print open the console with Cmd + Y to see it_ print(arrayApplicative) -func curriedAddition(a: Int)(b: Int) -> Int { - return a + b +func curriedAddition(a: Int) -> (Int) -> Int { + return { (b: Int) -> Int in + return a + b + } } curriedAddition <^> Optional(2) <*> Optional(3) -func curriedTimes(a: Int)(b: Int) -> Int { - return a * b +func curriedTimes(a: Int) -> (Int) -> Int { + return { (b: Int) -> Int in + return a * b + } } curriedTimes <^> Optional(5) <*> Optional(3) //: ## Monads -infix operator >>- { associativity left } +precedencegroup MonadicPrecedenceRight { + associativity: right + lowerThan: LogicalDisjunctionPrecedence + higherThan: AssignmentPrecedence +} + +precedencegroup MonadicPrecedenceLeft { + associativity: left + lowerThan: LogicalDisjunctionPrecedence + higherThan: AssignmentPrecedence +} + +infix operator >>- : MonadicPrecedenceLeft +infix operator -<< : MonadicPrecedenceRight -func >>-(a: T?, f: T -> U?) -> U? { +func >>-(a: T?, f: (T) -> U?) -> U? { return a.flatMap(f) } func half(a: Int) -> Int? { - return a % 2 == 0 ? a / 2 : .None + return a % 2 == 0 ? a / 2 : .none } Optional(3) >>- half Optional(4) >>- half -Optional.None >>- half +Optional.none >>- half //: We can even chain >>- diff --git a/Functors-Applicatives-Monads-In-Pictures.playground/contents.xcplayground b/Functors-Applicatives-Monads-In-Pictures.playground/contents.xcplayground index ee7c14f..5da2641 100644 --- a/Functors-Applicatives-Monads-In-Pictures.playground/contents.xcplayground +++ b/Functors-Applicatives-Monads-In-Pictures.playground/contents.xcplayground @@ -1,4 +1,4 @@ - + \ No newline at end of file diff --git a/Functors-Applicatives-Monads-In-Pictures.playground/playground.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/Functors-Applicatives-Monads-In-Pictures.playground/playground.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/Functors-Applicatives-Monads-In-Pictures.playground/playground.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/Functors-Applicatives-Monads-In-Pictures.playground/playground.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/Functors-Applicatives-Monads-In-Pictures.playground/playground.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 0000000..0c67376 --- /dev/null +++ b/Functors-Applicatives-Monads-In-Pictures.playground/playground.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,5 @@ + + + + + diff --git a/Functors-Applicatives-Monads-In-Pictures.playground/timeline.xctimeline b/Functors-Applicatives-Monads-In-Pictures.playground/timeline.xctimeline index 9064524..11f3415 100644 --- a/Functors-Applicatives-Monads-In-Pictures.playground/timeline.xctimeline +++ b/Functors-Applicatives-Monads-In-Pictures.playground/timeline.xctimeline @@ -3,72 +3,72 @@ version = "3.0">