Last active
September 19, 2016 21:38
-
-
Save alimakki/d455c5411ee83268248277a5acbcd4a3 to your computer and use it in GitHub Desktop.
Swift 3 adaptation of some functional programming concepts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Swift 3.0 based on the code in the talk given on this video by Brandon Williams - Functional Programming in a Playground | |
// https://www.youtube.com/watch?v=estNbh2TF3E | |
import Foundation | |
extension Int { | |
func square() -> Int { | |
return self*self | |
} | |
func incr() -> Int { | |
return self + 1 | |
} | |
} | |
let xs = Array(1...100) | |
func square(x: Int) -> Int { | |
return x * x | |
} | |
func incr(x: Int) -> Int { | |
return x + 1 | |
} | |
xs.map(square) | |
infix operator |> : PipeTo | |
precedencegroup PipeTo { | |
associativity: left | |
} | |
func |> <A, B> (x: A, f: (A) -> B) -> B { | |
return f(x) | |
} | |
func |> <A, B, C> (f: @escaping (A) -> B, g: @escaping (B) -> C) -> ((A) -> C) { | |
return { a in | |
return g(f(a)) | |
} | |
} | |
3 |> square |> incr | |
3 |> (square |> incr) | |
func map <A, B> (f: @escaping (A) ->B) -> ([A]) -> [B] { | |
return { xs in | |
return xs.map(f) | |
} | |
} | |
xs |> map(f: square) |> map(f: incr) | |
xs |> map(f: square |> incr) | |
func filter <A> (p: @escaping (A) -> Bool) -> ([A]) -> [A] { | |
return { xs in | |
return xs.filter(p) | |
} | |
} | |
func isPrime(p: Int) -> Bool { | |
if p <= 1 { return false } | |
if p <= 3 { return true } | |
for i in 2...Int(sqrtf(Float(p))) { | |
if p % i == 0 { return false } | |
} | |
return true | |
} | |
xs |> map(f: square |> incr) |> filter(p: isPrime) | |
func map_from_reduce <A, B> (f: @escaping (A) -> B) -> ([A]) -> [B] { | |
return { xs in | |
return xs.reduce([]) { accum, x in | |
return accum + [f(x)] | |
} | |
} | |
} | |
xs |> map_from_reduce(f: square) | |
func filter_from_reduce <A> (p: @escaping (A) -> Bool) -> ([A]) -> [A] { | |
return { xs in | |
return xs.reduce([]) { accum, x in | |
return p(x) ? accum + [x] : accum | |
} | |
} | |
} | |
xs |> filter_from_reduce(p: isPrime) | |
func take_from_reduce <A> (n: Int) -> ([A]) -> [A] { | |
return { xs in | |
return xs.reduce([]) { accum, x in | |
return accum.count < n ? accum + [x] : accum | |
} | |
} | |
} | |
xs |> take_from_reduce(n: 100) | |
func flatten_from_reduce <A> (xss: [[A]]) -> [A] { | |
return xss.reduce([]) { accum, xs in | |
return accum + xs | |
} | |
} | |
// figure this one out | |
//xs |> flatten_from_reduce(xss: [[xs |> take_from_reduce(n: 100)], [xs |> take_from_reduce(n: 100)]]) | |
func squaringTransducer <C> (reducer: @escaping (C, Int) -> C) -> ((C, Int) ->C ) { | |
return { accum, x in | |
return reducer(accum, x * x) | |
} | |
} | |
xs.reduce(0, +) | |
xs.reduce(0, squaringTransducer(reducer: +)) | |
func mapping<A, B, C> ( f: @escaping (A) -> B) -> ((@escaping (C, B) -> C) -> ((C, A) ->C )) { | |
return { reducer in | |
return { accum, a in | |
return reducer(accum, f(a)) | |
} | |
} | |
} | |
func filtering <A, C> (p: @escaping (A) -> Bool) -> ((@escaping (C, A) -> C) -> (C, A) ->C) { | |
return { reducer in | |
return { accum, x in | |
return p(x) ? reducer(accum, x) : accum | |
} | |
} | |
} | |
func append <A> (xs: [A], x: A) -> [A] { | |
return xs + [x] | |
} | |
xs.reduce([], append |> mapping(f: incr) |> mapping(f: square)) | |
xs.reduce([], append |> filtering(p: isPrime) |> mapping(f: incr) |> mapping(f: square)) | |
xs.reduce(0, (+) |> filtering(p: isPrime) |> mapping(f: incr) |> mapping(f: square)) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment