Skip to content

Instantly share code, notes, and snippets.

@alskipp
Last active February 3, 2018 22:56
Show Gist options
  • Select an option

  • Save alskipp/3fd25ee9a92bba329b2f to your computer and use it in GitHub Desktop.

Select an option

Save alskipp/3fd25ee9a92bba329b2f to your computer and use it in GitHub Desktop.

Revisions

  1. alskipp revised this gist Jul 29, 2015. 1 changed file with 5 additions and 5 deletions.
    10 changes: 5 additions & 5 deletions writer.swift
    Original file line number Diff line number Diff line change
    @@ -1,22 +1,22 @@
    infix operator >>- { associativity left precedence 150 }

    struct Writer<A, W: Monoid> {
    struct Writer<W: Monoid, A> {
    let runWriter: (value: A, log: W)

    init(_ a: A, _ w: W) { runWriter = (a, w) }
    }

    func >>- <A,B,W>(x: Writer<A,W>, f: A -> Writer<B, W>) -> Writer<B,W> {
    func >>- <W,A,B>(x: Writer<W,A>, f: A -> Writer<W,B>) -> Writer<W,B> {
    let (a, w) = x.runWriter
    let (a2, w2) = f(a).runWriter
    return Writer(a2, .mappend(w, w2))
    }

    func pure<A,W>(x: A) -> Writer<A,W> {
    func pure<W,A>(x: A) -> Writer<W,A> {
    return Writer(x, .mempty())
    }

    func logInt(x: Int) -> Writer<Int,[String]> {
    func logInt(x: Int) -> Writer<[String],Int> {
    return Writer(x, ["Got number: \(x)"])
    }

  2. alskipp revised this gist Jul 29, 2015. 1 changed file with 3 additions and 3 deletions.
    6 changes: 3 additions & 3 deletions writer.swift
    Original file line number Diff line number Diff line change
    @@ -6,17 +6,17 @@ struct Writer<A, W: Monoid> {
    init(_ a: A, _ w: W) { runWriter = (a, w) }
    }

    func >>- <A,W>(x: Writer<A, W>, f: A -> Writer<A,W>) -> Writer<A,W> {
    func >>- <A,B,W>(x: Writer<A,W>, f: A -> Writer<B, W>) -> Writer<B,W> {
    let (a, w) = x.runWriter
    let (a2, w2) = f(a).runWriter
    return Writer(a2, .mappend(w, w2))
    }

    func pure<A,W>(x:A) -> Writer<A,W> {
    func pure<A,W>(x: A) -> Writer<A,W> {
    return Writer(x, .mempty())
    }

    func logInt(x: Int) -> Writer<Int, [String]> {
    func logInt(x: Int) -> Writer<Int,[String]> {
    return Writer(x, ["Got number: \(x)"])
    }

  3. alskipp revised this gist Jul 28, 2015. 1 changed file with 26 additions and 0 deletions.
    26 changes: 26 additions & 0 deletions writer.swift
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,26 @@
    infix operator >>- { associativity left precedence 150 }

    struct Writer<A, W: Monoid> {
    let runWriter: (value: A, log: W)

    init(_ a: A, _ w: W) { runWriter = (a, w) }
    }

    func >>- <A,W>(x: Writer<A, W>, f: A -> Writer<A,W>) -> Writer<A,W> {
    let (a, w) = x.runWriter
    let (a2, w2) = f(a).runWriter
    return Writer(a2, .mappend(w, w2))
    }

    func pure<A,W>(x:A) -> Writer<A,W> {
    return Writer(x, .mempty())
    }

    func logInt(x: Int) -> Writer<Int, [String]> {
    return Writer(x, ["Got number: \(x)"])
    }

    let multLog = logInt(2) >>- { a in logInt(7) >>- { b in pure(a * b) }}
    let x = multLog.runWriter
    x.value // 14
    x.log // ["Got number: 2", "Got number: 7"]
  4. alskipp revised this gist Jul 28, 2015. 1 changed file with 15 additions and 0 deletions.
    15 changes: 15 additions & 0 deletions monoid.swift
    Original file line number Diff line number Diff line change
    @@ -25,6 +25,16 @@ extension Array: Monoid {
    }
    }

    extension String: Monoid {
    static func mempty() -> String {
    return ""
    }

    static func mappend(a: String, _ b: String) -> String {
    return a + b
    }
    }

    struct Sum<T: Num> {
    let value: T
    init(_ v: T) { value = v }
    @@ -61,6 +71,11 @@ let a2: [Int] = .mappend([1,2],[3,4,5]) // [1,2,3,4,5]
    let a3: [Int] = .mconcat([[1,2],[3],[4,5]]) // [1,2,3,4,5]


    let str1: String = .mempty() // ""
    let str2: String = .mappend("hello ", "world") // "hello world"
    let str3: String = .mconcat(["hell", "o", " ", "world", "!"]) // "hello world!"


    let s1: Sum<Int> = .mempty()
    s1.value // 0

  5. alskipp revised this gist Jul 28, 2015. 1 changed file with 4 additions and 5 deletions.
    9 changes: 4 additions & 5 deletions monoid.swift
    Original file line number Diff line number Diff line change
    @@ -4,14 +4,13 @@ extension Int: Num {}


    protocol Monoid {
    typealias t
    static func mempty() -> t
    static func mappend(a: t, _ b: t) -> t
    static func mconcat(a: [t]) -> t
    static func mempty() -> Self
    static func mappend(a: Self, _ b: Self) -> Self
    static func mconcat(a: [Self]) -> Self
    }

    extension Monoid {
    static func mconcat(a: [t]) -> t {
    static func mconcat(a: [Self]) -> Self {
    return a.reduce(mempty(), combine: mappend)
    }
    }
  6. alskipp revised this gist Jul 28, 2015. 1 changed file with 4 additions and 4 deletions.
    8 changes: 4 additions & 4 deletions monoid.swift
    Original file line number Diff line number Diff line change
    @@ -65,18 +65,18 @@ let a3: [Int] = .mconcat([[1,2],[3],[4,5]]) // [1,2,3,4,5]
    let s1: Sum<Int> = .mempty()
    s1.value // 0

    let s2: Sum<Int> = .mappend(Sum(1), Sum(2))
    let s2: Sum = .mappend(Sum(1), Sum(2))
    s2.value // 3

    let s3: Sum<Int> = .mconcat([1,2,3,4,5].map(Sum.init))
    let s3: Sum = .mconcat([1,2,3,4,5].map(Sum.init))
    s3.value // 15


    let p1: Product<Int> = .mempty()
    p1.value // 1

    let p2: Product<Int> = .mappend(Product(2), Product(3))
    let p2: Product = .mappend(Product(2), Product(3))
    p2.value // 6

    let p3: Product<Int> = .mconcat([1,2,3,4,5].map(Product.init))
    let p3: Product = .mconcat([1,2,3,4,5].map(Product.init))
    p3.value // 120
  7. alskipp created this gist Jul 28, 2015.
    82 changes: 82 additions & 0 deletions monoid.swift
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,82 @@
    // erm… this Num protocol is useless, but let's overlook this bit for now, shall we?
    protocol Num: IntegerLiteralConvertible, IntegerArithmeticType {}
    extension Int: Num {}


    protocol Monoid {
    typealias t
    static func mempty() -> t
    static func mappend(a: t, _ b: t) -> t
    static func mconcat(a: [t]) -> t
    }

    extension Monoid {
    static func mconcat(a: [t]) -> t {
    return a.reduce(mempty(), combine: mappend)
    }
    }

    extension Array: Monoid {
    static func mempty() -> [Element] {
    return []
    }

    static func mappend(a: [Element], _ b: [Element]) -> [Element] {
    return a + b
    }
    }

    struct Sum<T: Num> {
    let value: T
    init(_ v: T) { value = v }
    }

    extension Sum: Monoid {
    static func mempty() -> Sum<T> {
    return Sum(0)
    }

    static func mappend(a: Sum<T>, _ b: Sum<T>) -> Sum<T> {
    return Sum(a.value + b.value)
    }
    }

    struct Product<T: Num> {
    let value: T
    init(_ v: T) { value = v }
    }

    extension Product: Monoid {
    static func mempty() -> Product<T> {
    return Product(1)
    }

    static func mappend(a: Product<T>, _ b: Product<T>) -> Product<T> {
    return Product(a.value * b.value)
    }
    }


    let a1: [Int] = .mempty() // []
    let a2: [Int] = .mappend([1,2],[3,4,5]) // [1,2,3,4,5]
    let a3: [Int] = .mconcat([[1,2],[3],[4,5]]) // [1,2,3,4,5]


    let s1: Sum<Int> = .mempty()
    s1.value // 0

    let s2: Sum<Int> = .mappend(Sum(1), Sum(2))
    s2.value // 3

    let s3: Sum<Int> = .mconcat([1,2,3,4,5].map(Sum.init))
    s3.value // 15


    let p1: Product<Int> = .mempty()
    p1.value // 1

    let p2: Product<Int> = .mappend(Product(2), Product(3))
    p2.value // 6

    let p3: Product<Int> = .mconcat([1,2,3,4,5].map(Product.init))
    p3.value // 120