Skip to content

Commit

Permalink
Add episode 33
Browse files Browse the repository at this point in the history
  • Loading branch information
stephencelis committed Oct 17, 2018
1 parent 22dfa78 commit 18babca
Show file tree
Hide file tree
Showing 6 changed files with 185 additions and 1 deletion.
5 changes: 5 additions & 0 deletions 0033-protocol-witnesses-pt1/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
## [Point-Free](https://www.pointfree.co)

> #### This directory contains code from Point-Free Episode: [Protocol Witnesses: Part 1](https://www.pointfree.co/episodes/ep33-protocol-witnesses-part-1)
>
> Protocols are a great tool for abstraction, but aren’t the only one. This week we begin to explore the tradeoffs of using protocols by highlighting a few areas in which they fall short in order to demonstrate how we can recover from these problems using a different tool and different tradeoffs.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

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>
155 changes: 155 additions & 0 deletions 0033-protocol-witnesses-pt1/Witnesses.playground/Contents.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@

protocol Describable {
var describe: String { get }
}

struct PostgresConnInfo {
var database: String
var hostname: String
var password: String
var port: Int
var user: String
}

let localhostPostgres = PostgresConnInfo(
database: "pointfreeco_development",
hostname: "localhost",
password: "",
port: 5432,
user: "pointfreeco"
)

//extension PostgresConnInfo: Describable {
// var describe: String {
// return "PostgresConnInfo(database: \"\(self.database)\", hostname: \"\(self.hostname)\", password: \"\(self.password)\", port: \"\(self.port)\", user: \"\(self.user)\")"
// }
//}

//extension PostgresConnInfo: Describable {
// var describe: String {
// return """
//PostgresConnInfo(
// database: \"\(self.database)\",
// hostname: \"\(self.hostname)\",
// password: \"\(self.password)\",
// port: \"\(self.port)\",
// user: \"\(self.user)\"
//)
//"""
// }
//}

extension PostgresConnInfo: Describable {
var describe: String {
return "postgres://\(self.user):\(self.password)@\(self.hostname):\(self.port)/\(self.database)"
}
}

print(localhostPostgres.describe)

extension Int: Describable {
var describe: String {
return "\(self)"
}
}

2.describe

protocol EmptyInitializable {
init()
}

extension String: EmptyInitializable {
}
extension Array: EmptyInitializable {
}
extension Int: EmptyInitializable {
init() {
self = 1
}
}
extension Optional: EmptyInitializable {
init() {
self = nil
}
}

[1, 2, 3].reduce(0, +)

extension Array {
func reduce<Result: EmptyInitializable>(_ accumulation: (Result, Element) -> Result) -> Result {
return self.reduce(Result(), accumulation)
}
}

[1, 2, 3].reduce(+)
[[1, 2], [], [3, 4]].reduce(+)
["Hello", " ", "Blob"].reduce(+)

protocol Combinable {
func combine(with other: Self) -> Self
}

struct Combining<A> {
let combine: (A, A) -> A
}

extension Int: Combinable {
func combine(with other: Int) -> Int {
return self * other
}
}
extension String: Combinable {
func combine(with other: String) -> String {
return self + other
}
}
extension Array: Combinable {
func combine(with other: Array) -> Array {
return self + other
}
}
extension Optional: Combinable {
func combine(with other: Optional) -> Optional {
return self ?? other
}
}

extension Array where Element: Combinable {
func reduce(_ initial: Element) -> Element {
return self.reduce(initial) { $0.combine(with: $1) }
}
}

extension Array /* where Element: Combinable */ {
func reduce(_ initial: Element, _ combining: Combining<Element>) -> Element {
return self.reduce(initial, combining.combine)
}
}

[1, 2, 3].reduce(1)
[[1, 2], [], [3, 4]].reduce([])
[nil, nil, 3].reduce(nil)

let sum = Combining<Int>(combine: +)
[1, 2, 3, 4].reduce(0, sum)

let product = Combining<Int>(combine: *)
[1, 2, 3, 4].reduce(1, product)


extension Array where Element: Combinable & EmptyInitializable {
func reduce() -> Element {
return self.reduce(Element()) { $0.combine(with: $1) }
}
}

[1, 2, 3, 4].reduce()
[[1, 2], [], [3, 4]].reduce()
[nil, nil, 3].reduce()

//extension Int: Combinable {
// func combine(with other: Int) -> Int {
// return self * other
// }
//}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<playground version='5.0' target-platform='macos'>
<timeline fileName='timeline.xctimeline'/>
</playground>
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,6 @@ This repository is the home of code written on episodes of
1. [An HTML DSL](0028-html-dsl)
1. [DSLs vs. Templating Languages](0029-dsls-vs-templating-languages)
1. [Composable Randomness](0030-composable-randomness)
1. [Decodable Randomness](0031-arbitrary-pt1)
1. [Decodable Randomness: Part 1](0031-arbitrary-pt1)
1. [Decodable Randomness: Part 2](0032-arbitrary-pt2)
1. [Protocol Witnesses: Part 1](0033-protocol-witnesses-pt1))

0 comments on commit 18babca

Please sign in to comment.