Skip to content

Instantly share code, notes, and snippets.

@elm4ward
Last active April 21, 2017 11:35
Show Gist options
  • Save elm4ward/e4aa241435105472ea0b42f0f847ecd3 to your computer and use it in GitHub Desktop.
Save elm4ward/e4aa241435105472ea0b42f0f847ecd3 to your computer and use it in GitHub Desktop.
let mark = Array(repeating: "-", count: 40).joined(separator: "")
func chapter(_ s: String, line: Int = #line) { print("\n", "// " + mark, "// \(s) - line: \(line)", "// " + mark, separator: "\n")}
func section(_ s: String, line: Int = #line) { print("\n", "# \(s)", mark, separator: "\n")}
import struct CoreGraphics.CGFloat
// ----------------------------------------------------------------------------------------------------
// MARK: - Bi-directional Type Inference
//
// http://elm4ward.github.io/swift/generics/type/inference/2016/05/01/bidirectional.html
//
// It does not matter at what point you provide the necessary type information for generics, as long as it is enough and not ambiguous.
// And it is so cool to have generic NSUSerDefaults.
//
// 1. From Leaf to Root
// 2. From Root to Leaf
// 3. ... hmm ... lets see
// 4. Palau code
// ----------------------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------------------
// MARK: - 1. From Leaf to Root
// ----------------------------------------------------------------------------------------------------
chapter("1. From Leaf to Root")
// a)
// ok - list of Int - makes sense
section("ints: [1, 2, 3, 4]")
let ints = [1, 2, 3, 4]
print(type(of:ints))
// b)
// ok - list of Double - makes sense
section("doubles: [1.0, 2.0, 3.0, 4.0]")
let doubles = [1.0, 2.0, 3.0, 4.0]
print(type(of:doubles))
// c)
// ok - list of Optional Double - makes sense
section("maybeDoubles: [Optional.Some(1.0), 2.0, 3.0, 4.0]")
let maybeDoubles = [
// the first one will make the array filled with optionals
Optional.some(1.0),
// the next doubles will be automatically wrapped
2.0,
3.0,
4.0
]
print(type(of:maybeDoubles))
// d)
// ok - list of Double tuple - makes sense
section("tupleDouble: (1, 0), (2, 0), (3, 0), (4.0, 0.4)]")
let tupleDouble = [
(1, 0),
(2, 0),
(3, 0),
// the last entry will ensure the tuples in the array will have (Double, Double)
(4.0, 0.4)
]
print(type(of: tupleDouble))
// e)
// ok - list of tuple Int and Optional Int - makes sense
section("tupleInt: [(1, Optional.None), (2, 0), (3, 0), (4, 0)]")
let tupleInt = [
(1, Optional.none),
(2, 0),
(3, 0),
(4, 0)
]
print(type(of:tupleInt))
// ----------------------------------------------------------------------------------------------------
// MARK: - 2. From Root to Leaf
// ----------------------------------------------------------------------------------------------------
chapter("2. From Root to Leaf")
// a)
// hmm ... list of doubles
section("intsx: [1, 2, 3, 4]")
let intsX: [Double] = [1, 2, 3, 4]
print(type(of:intsX))
// b)
// hmm ... list of floats
section("doublesx: [1.0, 2.0, 3.0, 4.0]")
let doublesX: [Float] = [1.0, 2.0, 3.0, 4.0]
print(type(of:doublesX))
// c)
// hmm ... list of optional CGFloats
section("maybeDoublesx: [Optional.Some(1.0), 2, 3, 4]")
let maybeDoublesX: [CGFloat?] = [Optional.some(1.0), 2, 3, 4]
print(type(of:maybeDoublesX))
// d)
// hmm ... list of tuple Optional Float and Optional Double
section("tupleDoubleX: (1, 0), (2, 0), (3, 0), (4.0, 0.4)]")
let tupleDoubleX: [(Float?, Double?)] = [
(1, 0),
(2, 0),
(3, 0),
(4.0, 0.4)
]
print(type(of:tupleDoubleX))
// e)
// hmm ... optional list of optional tuple Optional Int and Optional CGFloat
section("tupleMaybeIntx: [(1, Optional.None), (2, 0), (3, 0), (4, 0)]")
let tupleMaybeIntx: [(Int?, CGFloat?)?]? = [
(1, Optional.none),
(2, 0),
(3, 0),
(4, 0)
]
print(type(of:tupleMaybeIntx))
// ----------------------------------------------------------------------------------------------------
// MARK: - 3. ... hmm ... lets see
// ----------------------------------------------------------------------------------------------------
chapter("3. ... hmm ... lets see")
section("array1: (1...10).map { $0 * $0 }.reduce(1, combine: +)")
let array1 = (1...10).map { $0 * $0 }.reduce(1, +)
print(type(of:array1))
// Uncomment to see error
section("NOT WORKING array2: Float = (1...10).map { $0 * $0 }.reduce(1, combine: +)")
//let array2: Float = (1...10).map { $0 * $0 }.reduce(1, combine: +)
section("array3 = (1...10).map { Float($0) * Float($0) }.reduce(1, combine: +)")
let array3 = (1...10).map { Float($0) * Float($0) }.reduce(1, +)
print(type(of:array3))
section("array4 = (1...10).map { Double($0 * $0) }.reduce(1, combine: +)")
let array4 = (1...10).map { Double($0 * $0) }.reduce(1, +)
print(type(of:array4))
// ----------------------------------------------------------------------------------------------------
// MARK: - 3. testing generic functions
// ----------------------------------------------------------------------------------------------------
chapter("3. testing generic functions")
section("lessThan<T: Comparable>(tx: T) -> T? -> Bool ")
func lessThan<T: Comparable>(tx: T) -> (T?) -> Bool {
return { t in t.map { $0 < tx } ?? false }
}
section("let lessThan10 = lessThan(10)")
let lessThan10 = lessThan(tx: 10)
print(type(of:lessThan10))
// -> Optional<Int> -> Bool
section("let lessThan10X: CGFloat? -> Bool = lessThan(10)")
let lessThan10X: (CGFloat?) -> Bool = lessThan(tx: 10)
print(type(of:lessThan10X))
// -> Optional<CGFloat> -> Bool
section("let lessThan10XX: DoublePredicate = lessThan(10)")
typealias DoublePredicate = (Double?) -> Bool
let lessThan10XX: DoublePredicate = lessThan(tx: 10)
print(type(of:lessThan10XX))
// -> Optional<Double> -> Bool
// ----------------------------------------------------------------------------------------------------
// MARK: - 4. Palau code
// ------------------------------------ ----------------------------------------------------------------
/*
Get https://github.com/symentis/Palau
Usage:
import Palau
import CoreGraphics
extension PalauDefaults {
// a generic NSUserDefault value
public static func floatConvertible<T: FloatLiteralConvertible>() -> PalauDefaultsEntry<T> {
return value("floatConvertible")
}
}
extension CGFloat: PalauDefaultable {
public typealias ValueType = CGFloat
}
var doubleEntry = PalauDefaults.floatConvertible()
let double = doubleEntry.value ?? 0
let doubleX = double + 1
doubleEntry.value = doubleX
var floatEntry: PalauDefaultsEntry<Float> = PalauDefaults.floatConvertible()
let float = floatEntry.value ?? 0
let floatX = float + 1
floatEntry.value = floatX
var cgfEntry: PalauDefaultsEntry<CGFloat> = PalauDefaults.floatConvertible()
let cgf = cgfEntry.value ?? 0
let cgfX = cgf + 1.4
cgfEntry.value = cgfX
*/
@elm4ward
Copy link
Author

swift 3 update

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment