Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 62 additions & 33 deletions Functors-Applicatives-Monads-In-Pictures.playground/Contents.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
//: Optional is just a type

enum MyOptional<T> {
case Some(T)
case None
case some(T)
case none
}

//: ## Functor
Expand All @@ -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<T, U>(a: T?, f: T -> U) -> U? {
func myMap<T, U>(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 <^><T, U>(f: T -> U, a: T?) -> U? {
infix operator <^> : ApplicativePrecedence

func <^><T, U>(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<U>(f: (Wrapped -> U)?) -> U? {
func apply<U>(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<U>(fs: [Element -> U]) -> [U] {
func apply<U>(fs: [(Element) -> U]) -> [U] {
var result = [U]()
for f in fs {
for element in self.map(f) {
Expand All @@ -82,50 +94,67 @@ extension Array {
}
}

infix operator <*> { associativity left }
infix operator <*> : ApplicativePrecedence

func <*><T, U>(f: (T -> U)?, a: T?) -> U? {
return a.apply(f)
func <*><T, U>(f: ((T) -> U)?, a: T?) -> U? {
return a.apply(f: f)
}

func <*><T, U>(f: [T -> U], a: [T]) -> [U] {
return a.apply(f)
func <*><T, U>(_ 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 >>-<T, U>(a: T?, f: T -> U?) -> U? {
func >>-<T, U>(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 >>-

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<playground version='5.0' target-platform='ios' requires-full-environment='true'>
<playground version='5.0' target-platform='ios'>
<timeline fileName='timeline.xctimeline'/>
</playground>
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict/>
</plist>
Original file line number Diff line number Diff line change
Expand Up @@ -3,72 +3,72 @@
version = "3.0">
<TimelineItems>
<LoggerValueHistoryTimelineItem
documentLocation = "#CharacterRangeLen=31&amp;CharacterRangeLoc=733&amp;EndingColumnNumber=32&amp;EndingLineNumber=20&amp;StartingColumnNumber=1&amp;StartingLineNumber=20&amp;Timestamp=458515349.401583"
documentLocation = "file:///Users/radioshaolin/Documents/Swift-Functors-Applicative-Monads-In-Pictures-Playground/Functors-Applicatives-Monads-In-Pictures.playground#CharacterRangeLen=31&amp;CharacterRangeLoc=733&amp;EndingColumnNumber=0&amp;EndingLineNumber=21&amp;StartingColumnNumber=1&amp;StartingLineNumber=20&amp;Timestamp=574441380.172964"
selectedRepresentationIndex = "0"
shouldTrackSuperviewWidth = "NO">
</LoggerValueHistoryTimelineItem>
<LoggerValueHistoryTimelineItem
documentLocation = "#CharacterRangeLen=6&amp;CharacterRangeLoc=838&amp;EndingColumnNumber=30&amp;EndingLineNumber=25&amp;StartingColumnNumber=24&amp;StartingLineNumber=25&amp;Timestamp=458515349.4017"
documentLocation = "file:///Users/radioshaolin/Documents/Swift-Functors-Applicative-Monads-In-Pictures-Playground/Functors-Applicatives-Monads-In-Pictures.playground#CharacterRangeLen=6&amp;CharacterRangeLoc=838&amp;EndingColumnNumber=30&amp;EndingLineNumber=24&amp;StartingColumnNumber=24&amp;StartingLineNumber=24&amp;Timestamp=574441380.17311"
selectedRepresentationIndex = "0"
shouldTrackSuperviewWidth = "NO">
</LoggerValueHistoryTimelineItem>
<LoggerValueHistoryTimelineItem
documentLocation = "#CharacterRangeLen=28&amp;CharacterRangeLoc=913&amp;EndingColumnNumber=29&amp;EndingLineNumber=28&amp;StartingColumnNumber=1&amp;StartingLineNumber=28&amp;Timestamp=458515349.401781"
documentLocation = "file:///Users/radioshaolin/Documents/Swift-Functors-Applicative-Monads-In-Pictures-Playground/Functors-Applicatives-Monads-In-Pictures.playground#CharacterRangeLen=28&amp;CharacterRangeLoc=913&amp;EndingColumnNumber=0&amp;EndingLineNumber=29&amp;StartingColumnNumber=1&amp;StartingLineNumber=28&amp;Timestamp=574441380.173227"
selectedRepresentationIndex = "0"
shouldTrackSuperviewWidth = "NO">
</LoggerValueHistoryTimelineItem>
<LoggerValueHistoryTimelineItem
documentLocation = "#CharacterRangeLen=6&amp;CharacterRangeLoc=1148&amp;EndingColumnNumber=36&amp;EndingLineNumber=40&amp;StartingColumnNumber=30&amp;StartingLineNumber=40&amp;Timestamp=458515349.401858"
documentLocation = "file:///Users/radioshaolin/Documents/Swift-Functors-Applicative-Monads-In-Pictures-Playground/Functors-Applicatives-Monads-In-Pictures.playground#CharacterRangeLen=6&amp;CharacterRangeLoc=1153&amp;EndingColumnNumber=39&amp;EndingLineNumber=39&amp;StartingColumnNumber=33&amp;StartingLineNumber=39&amp;Timestamp=574441380.173345"
selectedRepresentationIndex = "0"
shouldTrackSuperviewWidth = "NO">
</LoggerValueHistoryTimelineItem>
<LoggerValueHistoryTimelineItem
documentLocation = "#CharacterRangeLen=30&amp;CharacterRangeLoc=1303&amp;EndingColumnNumber=31&amp;EndingLineNumber=49&amp;StartingColumnNumber=1&amp;StartingLineNumber=49&amp;Timestamp=458515349.401932"
documentLocation = "file:///Users/radioshaolin/Documents/Swift-Functors-Applicative-Monads-In-Pictures-Playground/Functors-Applicatives-Monads-In-Pictures.playground#CharacterRangeLen=30&amp;CharacterRangeLoc=1603&amp;EndingColumnNumber=0&amp;EndingLineNumber=62&amp;StartingColumnNumber=1&amp;StartingLineNumber=61&amp;Timestamp=574441380.173581"
selectedRepresentationIndex = "0"
shouldTrackSuperviewWidth = "NO">
</LoggerValueHistoryTimelineItem>
<LoggerValueHistoryTimelineItem
documentLocation = "#CharacterRangeLen=7&amp;CharacterRangeLoc=1576&amp;EndingColumnNumber=8&amp;EndingLineNumber=60&amp;StartingColumnNumber=1&amp;StartingLineNumber=60&amp;Timestamp=458515349.402004"
documentLocation = "file:///Users/radioshaolin/Documents/Swift-Functors-Applicative-Monads-In-Pictures-Playground/Functors-Applicatives-Monads-In-Pictures.playground#CharacterRangeLen=7&amp;CharacterRangeLoc=1900&amp;EndingColumnNumber=0&amp;EndingLineNumber=73&amp;StartingColumnNumber=1&amp;StartingLineNumber=72&amp;Timestamp=574441380.1737061"
selectedRepresentationIndex = "0"
shouldTrackSuperviewWidth = "NO">
</LoggerValueHistoryTimelineItem>
<LoggerValueHistoryTimelineItem
documentLocation = "#CharacterRangeLen=6&amp;CharacterRangeLoc=2237&amp;EndingColumnNumber=23&amp;EndingLineNumber=94&amp;StartingColumnNumber=17&amp;StartingLineNumber=94&amp;Timestamp=458515390.356103"
documentLocation = "file:///Users/radioshaolin/Documents/Swift-Functors-Applicative-Monads-In-Pictures-Playground/Functors-Applicatives-Monads-In-Pictures.playground#CharacterRangeLen=8&amp;CharacterRangeLoc=2577&amp;EndingColumnNumber=17&amp;EndingLineNumber=106&amp;StartingColumnNumber=9&amp;StartingLineNumber=106&amp;Timestamp=574441380.173821"
selectedRepresentationIndex = "0"
shouldTrackSuperviewWidth = "NO">
</LoggerValueHistoryTimelineItem>
<LoggerValueHistoryTimelineItem
documentLocation = "#CharacterRangeLen=6&amp;CharacterRangeLoc=2296&amp;EndingColumnNumber=11&amp;EndingLineNumber=96&amp;StartingColumnNumber=5&amp;StartingLineNumber=96&amp;Timestamp=458515571.274726"
documentLocation = "file:///Users/radioshaolin/Documents/Swift-Functors-Applicative-Monads-In-Pictures-Playground/Functors-Applicatives-Monads-In-Pictures.playground#CharacterRangeLen=6&amp;CharacterRangeLoc=2638&amp;EndingColumnNumber=28&amp;EndingLineNumber=108&amp;StartingColumnNumber=22&amp;StartingLineNumber=108&amp;Timestamp=574441380.173934"
selectedRepresentationIndex = "0"
shouldTrackSuperviewWidth = "NO">
</LoggerValueHistoryTimelineItem>
<LoggerValueHistoryTimelineItem
documentLocation = "#CharacterRangeLen=47&amp;CharacterRangeLoc=2585&amp;EndingColumnNumber=48&amp;EndingLineNumber=105&amp;StartingColumnNumber=1&amp;StartingLineNumber=105&amp;Timestamp=458515611.936015"
documentLocation = "file:///Users/radioshaolin/Documents/Swift-Functors-Applicative-Monads-In-Pictures-Playground/Functors-Applicatives-Monads-In-Pictures.playground#CharacterRangeLen=46&amp;CharacterRangeLoc=2971&amp;EndingColumnNumber=42&amp;EndingLineNumber=119&amp;StartingColumnNumber=5&amp;StartingLineNumber=116&amp;Timestamp=574441380.174047"
selectedRepresentationIndex = "0"
shouldTrackSuperviewWidth = "NO">
</LoggerValueHistoryTimelineItem>
<LoggerValueHistoryTimelineItem
documentLocation = "#CharacterRangeLen=44&amp;CharacterRangeLoc=2697&amp;EndingColumnNumber=45&amp;EndingLineNumber=111&amp;StartingColumnNumber=1&amp;StartingLineNumber=111&amp;Timestamp=458515625.997398"
documentLocation = "file:///Users/radioshaolin/Documents/Swift-Functors-Applicative-Monads-In-Pictures-Playground/Functors-Applicatives-Monads-In-Pictures.playground#CharacterRangeLen=101&amp;CharacterRangeLoc=3068&amp;EndingColumnNumber=39&amp;EndingLineNumber=127&amp;StartingColumnNumber=0&amp;StartingLineNumber=122&amp;Timestamp=574441380.174158"
selectedRepresentationIndex = "0"
shouldTrackSuperviewWidth = "NO">
</LoggerValueHistoryTimelineItem>
<LoggerValueHistoryTimelineItem
documentLocation = "#CharacterRangeLen=20&amp;CharacterRangeLoc=2939&amp;EndingColumnNumber=21&amp;EndingLineNumber=125&amp;StartingColumnNumber=1&amp;StartingLineNumber=125&amp;Timestamp=458515783.455502"
documentLocation = "file:///Users/radioshaolin/Documents/Swift-Functors-Applicative-Monads-In-Pictures-Playground/Functors-Applicatives-Monads-In-Pictures.playground#CharacterRangeLen=23&amp;CharacterRangeLoc=3708&amp;EndingColumnNumber=14&amp;EndingLineNumber=154&amp;StartingColumnNumber=32&amp;StartingLineNumber=151&amp;Timestamp=574441380.174269"
selectedRepresentationIndex = "0"
shouldTrackSuperviewWidth = "NO">
</LoggerValueHistoryTimelineItem>
<LoggerValueHistoryTimelineItem
documentLocation = "#CharacterRangeLen=22&amp;CharacterRangeLoc=2981&amp;EndingColumnNumber=23&amp;EndingLineNumber=127&amp;StartingColumnNumber=1&amp;StartingLineNumber=127&amp;Timestamp=458515819.595214"
documentLocation = "file:///Users/radioshaolin/Documents/Swift-Functors-Applicative-Monads-In-Pictures-Playground/Functors-Applicatives-Monads-In-Pictures.playground#CharacterRangeLen=22&amp;CharacterRangeLoc=3753&amp;EndingColumnNumber=16&amp;EndingLineNumber=156&amp;StartingColumnNumber=15&amp;StartingLineNumber=155&amp;Timestamp=574441380.174378"
selectedRepresentationIndex = "0"
shouldTrackSuperviewWidth = "NO">
</LoggerValueHistoryTimelineItem>
<LoggerValueHistoryTimelineItem
documentLocation = "#CharacterRangeLen=20&amp;CharacterRangeLoc=2960&amp;EndingColumnNumber=21&amp;EndingLineNumber=126&amp;StartingColumnNumber=1&amp;StartingLineNumber=126&amp;Timestamp=458515819.595293"
documentLocation = "file:///Users/radioshaolin/Documents/Swift-Functors-Applicative-Monads-In-Pictures-Playground/Functors-Applicatives-Monads-In-Pictures.playground#CharacterRangeLen=20&amp;CharacterRangeLoc=3732&amp;EndingColumnNumber=14&amp;EndingLineNumber=155&amp;StartingColumnNumber=15&amp;StartingLineNumber=154&amp;Timestamp=574441380.174491"
selectedRepresentationIndex = "0"
shouldTrackSuperviewWidth = "NO">
</LoggerValueHistoryTimelineItem>
<LoggerValueHistoryTimelineItem
documentLocation = "#CharacterRangeLen=39&amp;CharacterRangeLoc=3032&amp;EndingColumnNumber=40&amp;EndingLineNumber=131&amp;StartingColumnNumber=1&amp;StartingLineNumber=131&amp;Timestamp=458515835.80059"
documentLocation = "file:///Users/radioshaolin/Documents/Swift-Functors-Applicative-Monads-In-Pictures-Playground/Functors-Applicatives-Monads-In-Pictures.playground#CharacterRangeLen=39&amp;CharacterRangeLoc=3804&amp;EndingColumnNumber=33&amp;EndingLineNumber=160&amp;StartingColumnNumber=21&amp;StartingLineNumber=158&amp;Timestamp=574441380.174602"
selectedRepresentationIndex = "0"
shouldTrackSuperviewWidth = "NO">
</LoggerValueHistoryTimelineItem>
Expand Down