Permalink
Browse files

Updated for Swift 3.0: Variance, Sequence, Error Handling,Bitwise,

Trampoline and Flatmap

The Swift and C playground still need a few changes.

 2015-09-VariancePlayground.playground/Contents.swift
        modified:
2015-09-VariancePlayground.playground/contents.xcplayground
        deleted:
2015-09-VariancePlayground.playground/timeline.xctimeline
        modified:
2015-11-12-SequenceTypeGeneratorTypePlayground.playground/Contents.swift
        modified:
2015-11-Swift2ErrorHandlingPlayground.playground/Contents.swift
        deleted:
2015-11-Swift2ErrorHandlingPlayground.playground/timeline.xctimeline
        modified:
2016-02-5-Bitwise-Playground.playground/Contents.swift
        deleted:
2016-02-5-Bitwise-Playground.playground/timeline.xctimeline
        modified:
2016-05-05-recursive-trampoline.playground/Contents.swift
  • Loading branch information...
uraimo committed Sep 6, 2016
1 parent 07e533c commit c7436ecb90c50eaa6685be50d953e8c6a84b2097
@@ -9,9 +9,9 @@ func innerAnyAny(p1:Any) -> Any{ return 1 }
func innerIntInt(p1:Int) -> Int{ return 1 }
func innerIntAny(p1:Int) -> Any{ return 1 }
testVariance(innerIntAny)
testVariance(innerAnyInt)
testVariance(innerAnyAny)
testVariance(innerIntInt)
testVariance(foo:innerIntAny)
testVariance(foo:innerAnyInt)
testVariance(foo:innerAnyAny)
testVariance(foo:innerIntInt)
@@ -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>
@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Timeline
version = "3.0">
<TimelineItems>
</TimelineItems>
</Timeline>
@@ -7,7 +7,7 @@
//:Let's build a simple generator that produces numbers from the well known Fibonacci sequence:
class FibonacciGenerator : GeneratorType {
class FibonacciIterator : IteratorProtocol {
var last = (0,1)
var endAt:Int
var lastIteration = 0
@@ -30,7 +30,7 @@ class FibonacciGenerator : GeneratorType {
//: To return a finite sequence we need an additional constructor that we'll use to specify the sequence length and return *nil* instead of a new element when we reach it. There is not much else to see here other than the tuple swap trick that save us a few lines, but let's see how to use this generator:
var fg = FibonacciGenerator(end:10)
var fg = FibonacciIterator(end:10)
while let fib = fg.next() {
print(fib)
@@ -41,15 +41,15 @@ while let fib = fg.next() {
//: Implementing a **SequenceType** for this generator is straightforward:
class FibonacciSequence : SequenceType {
class FibonacciSequence : Sequence {
var endAt:Int
init(end:Int){
endAt = end
}
func generate() -> FibonacciGenerator{
return FibonacciGenerator(end: endAt)
func makeIterator() -> FibonacciIterator{
return FibonacciIterator(end: endAt)
}
}
@@ -62,18 +62,18 @@ for f in FibonacciSequence(end: 10) {
//: But there is no need to declare the generator as a separated entity, we can use the **anyGenerator** utility method with the **AnyGenerator<T>** class to make this example more compact:
class CompactFibonacciSequence : SequenceType {
class CompactFibonacciSequence : Sequence {
var endAt:Int
init(end:Int){
endAt = end
}
func generate() -> AnyGenerator<Int> {
func makeIterator() -> AnyIterator<Int> {
var last = (0,1)
var lastIteration = 0
return AnyGenerator{
return AnyIterator{
guard lastIteration<self.endAt else {
return nil
}
@@ -96,7 +96,7 @@ for f in CompactFibonacciSequence(end: 10) {
var last = (2,1)
var c = 0
let lucas = AnyGenerator{
let lucas = AnyIterator{
()->Int? in
guard c<10 else {
return nil
@@ -123,21 +123,21 @@ func luc(n:Int)->Int {
}
c = 0
var compactLucas = AnyGenerator{ c<10 ? luc(c+1): nil }
var compactLucas = AnyIterator{ c<10 ? luc(n: c+1): nil }
let a2 = Array(compactLucas) //[2, 1, 3, 4, 7, 11, 18, 29, 47, 76]
//: To try out some of the functional(ish) facilities that **SequenceType** provide, we'll now build a derived sequence that will only return *even* numbers from the Lucas sequence:
c = 0
var evenCompactLucas = AnyGenerator{ c<10 ? luc(c+1): nil }.filter({$0 % 2 == 0})
var evenCompactLucas = AnyIterator{ c<10 ? luc(n: c+1): nil }.filter({$0 % 2 == 0})
let a3 = Array(evenCompactLucas) //[2, 4, 18, 76]
//: But now, what it we remove the nil termination requirement described above to build an infinite sequence of all the possible Lucas numbers?
c = 0
var infiniteLucas = AnyGenerator{luc(c+1)}
var infiniteLucas = AnyIterator{luc(n: c+1)}
let a4 = Array(infiniteLucas.prefix(10)) //[2, 1, 3, 4, 7, 11, 18, 29, 47, 76]
@@ -156,10 +156,10 @@ for var f in onlyEvenLucas.prefix(10){
//: Let's see visually what's happening if we remove *.lazy* using a more verbose infinite sequence of integers that will print some text every time a value is requested from the generator:
class InfiniteSequence :SequenceType {
func generate() -> AnyGenerator<Int> {
class InfiniteSequence :Sequence {
func makeIterator() -> AnyIterator<Int> {
var i = 0
return AnyGenerator{
return AnyIterator{
print("# Returning "+String(i))
i += 1
return i
@@ -168,7 +168,7 @@ class InfiniteSequence :SequenceType {
}
//: Again, remove ".lazy" and grab a coffee...
var fs = InfiniteSequence().lazy.filter({$0 % 2 == 0}).generate()
var fs = InfiniteSequence().lazy.filter({$0 % 2 == 0}).makeIterator()
for i in 1...5 {
print(fs.next())
@@ -4,7 +4,7 @@
/////////////////////////////////////
//Simple Example
enum MyError : ErrorType{
enum MyError : Error{
case AnError
case AnotherError
case JustAnotherError
@@ -40,7 +40,7 @@ do{
/////////////////////////////////////
// More complex example
enum MyError2 : ErrorType{
enum MyError2 : Error{
case GenericError
case DetailedError(String)
case NumericError(Int)
@@ -69,7 +69,7 @@ do{
}catch MyError2.NumericError(let number) where number>0{
print("Error with id: "+String(number))
}catch{
print("Something else happened: "+String(error))
print("Something else happened: "+String(describing:error))
}
@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Timeline
version = "3.0">
<TimelineItems>
</TimelineItems>
</Timeline>
@@ -15,7 +15,7 @@ var int3:UInt8 = 0xA7
//: Where are we?? We can check the size of the Int type with strideof(or sizeof in this case) to understand on wich platform we are
//:
strideof(Int)==strideof(Int32) //Are we on a 32bits platform? Nope.
MemoryLayout<Int>.stride==MemoryLayout<Int32>.stride //Are we on a 32bits platform? Nope.
//: Swift does not perform implicit conversions
//:
@@ -134,7 +134,7 @@ x = x ^ y // x is now 2
//: Double negation bitwise operator ~~
//:
prefix operator ~~ {}
prefix operator ~~
prefix func ~~(value: UInt8)->UInt8{
return (value>0) ? 1 : 0
}
@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Timeline
version = "3.0">
<TimelineItems>
</TimelineItems>
</Timeline>
@@ -11,7 +11,7 @@ func tri(n:Int)->Int{
if n <= 0 {
return 0
}
return n+tri(n-1)
return n+tri(n: n-1)
}
//: With tail recursion
@@ -20,10 +20,10 @@ func ttri(n:Int, acc:Int=0)->Int {
if n<1 {
return acc
}
return ttri(n-1,acc:acc+n)
return ttri(n: n-1,acc:acc+n)
}
ttri(300)
ttri(n: 300)
let verify = (300*(300+1))/2
//: With a trampoline
@@ -41,12 +41,12 @@ func tritr(n:Int)->Int {
}
return .Call({
()->Result<Int> in
return ttri(n-1,acc: acc+n)
return ttri(n: n-1,acc: acc+n)
})
}
let acc = 0
var res = ttri(n,acc:acc)
var res = ttri(n: n,acc:acc)
while true {
switch res {
@@ -59,11 +59,11 @@ func tritr(n:Int)->Int {
}
tritr(300)
tritr(n: 300)
//: withTrampoline utility function, that turns CPS functions into functions with an embedded trampoline
func withTrampoline<V,A>(f:(V,A)->Result<A>) -> ((V,A)->A){
func withTrampoline<V,A>(f:@escaping (V,A)->Result<A>) -> ((V,A)->A){
return { (value:V,accumulator:A)->A in
var res = f(value,accumulator)
@@ -78,17 +78,17 @@ func withTrampoline<V,A>(f:(V,A)->Result<A>) -> ((V,A)->A){
}
}
var fin: (n:Int, a:Int) -> Result<Int> = {_,_ in .Done(0)}
var fin: (_ n:Int, _ a:Int) -> Result<Int> = {_,_ in .Done(0)}
fin = { (n:Int, a:Int) -> Result<Int> in
if n<1 {
return .Done(a)
}
return .Call({
()->Result<Int> in
return fin(n: n-1,a: a+n)
return fin(n-1,a+n)
})
}
let f = withTrampoline(fin)
let f = withTrampoline(f: fin)
f(30,0)
@@ -102,7 +102,7 @@ enum Result2<V,A>{
}
func withTrampoline2<V,A>(f:(V,A)->Result2<V,A>) -> ((V,A)->A){
func withTrampoline2<V,A>(f:@escaping (V,A)->Result2<V,A>) -> ((V,A)->A){
return { (value:V,accumulator:A)->A in
var res = f(value,accumulator)

0 comments on commit c7436ec

Please sign in to comment.