Skip to content

Instantly share code, notes, and snippets.

@mbrandonw
Last active October 18, 2020 16:56

Revisions

  1. mbrandonw revised this gist Dec 7, 2014. 1 changed file with 4 additions and 0 deletions.
    4 changes: 4 additions & 0 deletions transducer-type.swift
    Original file line number Diff line number Diff line change
    @@ -113,3 +113,7 @@ reduce(xs, [], append
    |> Filtering(isPrime)
    |> Mapping(square |> incr)
    )


    let compositeTransducer = FlatMapping(repeat(3)) |> Filtering(isPrime) |> Mapping(square |> incr)
    reduce(xs, 0, (+) |> compositeTransducer)
  2. mbrandonw revised this gist Dec 7, 2014. 1 changed file with 0 additions and 4 deletions.
    4 changes: 0 additions & 4 deletions transducer-type.swift
    Original file line number Diff line number Diff line change
    @@ -67,10 +67,6 @@ func |> <A, B, C> (lhs: Transducer<A, B>, rhs: Transducer<B, C>) -> Transducer<A
    return CompositionTransducer<A, B, C>(rhs, lhs)
    }

    func * <A, B, C> (lhs: Transducer<B, C>, rhs: Transducer<A, B>) -> Transducer<A, C> {
    return rhs |> lhs
    }

    class Mapping <B, A> : Transducer <B, A> {
    let f: A -> B
    init(_ f: A -> B) {
  3. mbrandonw renamed this gist Dec 7, 2014. 1 changed file with 0 additions and 0 deletions.
    File renamed without changes.
  4. mbrandonw created this gist Dec 7, 2014.
    119 changes: 119 additions & 0 deletions transducer-type.swif
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,119 @@
    import Foundation

    // A bunch of convenience things
    func const <A, B> (b: B) -> A -> B {
    return { _ in b }
    }
    func repeat <A> (n: Int) -> A -> [A] {
    return { a in
    return map(Array(1...n), const(a))
    }
    }
    infix operator |> {associativity left}
    func |> <A, B> (x: A, f: A -> B) -> B {
    return f(x)
    }
    func |> <A, B, C> (f: A -> B, g: B -> C) -> A -> C {
    return { g(f($0)) }
    }
    func append <A> (xs: [A], x: A) -> [A] {
    return xs + [x]
    }
    func square (x: Int) -> Int {
    return x*x
    }
    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
    }
    func incr (x: Int) -> Int {
    return x + 1
    }


    // Here's the good stuff

    class Transducer <A, B> {
    func step <R> (_: (R, A) -> R) -> (R, B) -> R {
    fatalError("should be overriden")
    }
    }

    class CompositionTransducer <A, B, C> : Transducer <A, C> {
    let lhs: Transducer<B, C>
    let rhs: Transducer<A, B>

    init (_ lhs: Transducer<B, C>, _ rhs: Transducer<A, B>) {
    self.lhs = lhs
    self.rhs = rhs
    }

    override func step <R> (reducer: (R, A) -> R) -> (R, C) -> R {
    return self.lhs.step(self.rhs.step(reducer))
    }
    }

    func |> <A, B, R> (reducer: (R, A) -> R, transducer: Transducer<A, B>) -> (R, B) -> R {
    return transducer.step(reducer)
    }

    func |> <A, B, C> (lhs: Transducer<A, B>, rhs: Transducer<B, C>) -> Transducer<A, C> {
    return CompositionTransducer<A, B, C>(rhs, lhs)
    }

    func * <A, B, C> (lhs: Transducer<B, C>, rhs: Transducer<A, B>) -> Transducer<A, C> {
    return rhs |> lhs
    }

    class Mapping <B, A> : Transducer <B, A> {
    let f: A -> B
    init(_ f: A -> B) {
    self.f = f
    }

    override func step <R> (reducer: (R, B) -> R) -> (R, A) -> R {
    return { accum, a in
    return reducer(accum, self.f(a))
    }
    }
    }

    class FlatMapping <B, A> : Transducer <B, A> {
    let f: A -> [B]
    init(_ f: A -> [B]) {
    self.f = f
    }

    override func step <R> (reducer: (R, B) -> R) -> (R, A) -> R {
    return { accum, a in
    return reduce(self.f(a), accum, reducer)
    }
    }
    }

    class Filtering <A> : Transducer <A, A> {
    let p: A -> Bool
    init (_ p: A -> Bool) {
    self.p = p
    }

    override func step <R> (reducer: (R, A) -> R) -> (R, A) -> R {
    return { accum, a in
    return self.p(a) ? reducer(accum, a) : accum
    }
    }
    }


    let xs = Array(1...100)
    reduce(xs, [], append
    |> FlatMapping(repeat(3))
    |> Filtering(isPrime)
    |> Mapping(square |> incr)
    )