-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1 from CodaFi/vacuum
Initial Commit
- Loading branch information
Showing
17 changed files
with
1,676 additions
and
1 deletion.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
// | ||
// ArrayZipper.swift | ||
// swiftz | ||
// | ||
// Created by Alexander Ronald Altman on 8/4/14. | ||
// Copyright (c) 2014 Maxwell Swadling. All rights reserved. | ||
// | ||
|
||
/// A zipper for arrays. Zippers are convenient ways of traversing and modifying the parts of a | ||
/// structure using a cursor to focus on its individual parts. | ||
public struct ArrayZipper<A> : ArrayLiteralConvertible { | ||
typealias Element = A | ||
|
||
/// The underlying array of values. | ||
public let values : [A] | ||
/// The position of the cursor within the Array. | ||
public let position : Int | ||
|
||
public init(_ values : [A] = [], _ position : Int = 0) { | ||
if position < 0 { | ||
self.position = 0 | ||
} else if position >= values.count { | ||
self.position = values.count - 1 | ||
} else { | ||
self.position = position | ||
} | ||
self.values = values | ||
} | ||
|
||
/// Creates an ArrayZipper pointing at the head of a given list of elements. | ||
public init(arrayLiteral elements : Element...) { | ||
self.init(elements, 0) | ||
} | ||
|
||
/// Creates an `ArrayZipper` with the cursor adjusted by n in the direction of the sign of the | ||
/// given value. | ||
public func move(n : Int = 1) -> ArrayZipper<A> { | ||
return ArrayZipper(values, position + n) | ||
} | ||
|
||
/// Creates an `ArrayZipper` with the cursor set to a given position value. | ||
public func moveTo(pos : Int) -> ArrayZipper<A> { | ||
return ArrayZipper(values, pos) | ||
} | ||
|
||
/// Returns whether the cursor of the receiver is at the end of its underlying Array. | ||
public var isAtEnd : Bool { | ||
return position >= (values.count - 1) | ||
} | ||
} | ||
|
||
extension ArrayZipper /*: Functor*/ { | ||
typealias B = Any | ||
typealias FB = ArrayZipper<B> | ||
|
||
public func fmap<B>(f : A -> B) -> ArrayZipper<B> { | ||
return ArrayZipper<B>(self.values.map(f), self.position) | ||
} | ||
} | ||
|
||
public func <^> <A, B>(f : A -> B, xz : ArrayZipper<A>) -> ArrayZipper<B> { | ||
return xz.fmap(f) | ||
} | ||
|
||
extension ArrayZipper /*: Copointed*/ { | ||
/// Extracts the value at the position of the receiver's cursor. | ||
/// | ||
/// This function is not total, but makes the guarantee that if `zipper.isAtEnd` returns false, | ||
/// it is safe to call. | ||
public func extract() -> A { | ||
return self.values[self.position] | ||
} | ||
} | ||
|
||
extension ArrayZipper /*: Comonad*/ { | ||
typealias FFA = ArrayZipper<ArrayZipper<A>> | ||
|
||
public func duplicate() -> ArrayZipper<ArrayZipper<A>> { | ||
return ArrayZipper<ArrayZipper<A>>((0 ..< self.values.count).map { ArrayZipper(self.values, $0) }, self.position) | ||
} | ||
|
||
public func extend<B>(f : ArrayZipper<A> -> B) -> ArrayZipper<B> { | ||
return ArrayZipper<B>((0 ..< self.values.count).map { f(ArrayZipper(self.values, $0)) }, self.position) | ||
} | ||
} | ||
|
||
public func ->> <A, B>(xz : ArrayZipper<A>, f: ArrayZipper<A> -> B) -> ArrayZipper<B> { | ||
return xz.extend(f) | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
// | ||
// Focus.h | ||
// Focus | ||
// | ||
// Created by Robert Widmann on 7/2/15. | ||
// Copyright © 2015 TypeLift. All rights reserved. | ||
// | ||
|
||
#import <Cocoa/Cocoa.h> | ||
|
||
//! Project version number for Focus. | ||
FOUNDATION_EXPORT double FocusVersionNumber; | ||
|
||
//! Project version string for Focus. | ||
FOUNDATION_EXPORT const unsigned char FocusVersionString[]; | ||
|
||
// In this header, you should import all the public headers of your framework using statements like #import <Focus/PublicHeader.h> | ||
|
||
|
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | ||
<plist version="1.0"> | ||
<dict> | ||
<key>CFBundleDevelopmentRegion</key> | ||
<string>en</string> | ||
<key>CFBundleExecutable</key> | ||
<string>$(EXECUTABLE_NAME)</string> | ||
<key>CFBundleIdentifier</key> | ||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string> | ||
<key>CFBundleInfoDictionaryVersion</key> | ||
<string>6.0</string> | ||
<key>CFBundleName</key> | ||
<string>$(PRODUCT_NAME)</string> | ||
<key>CFBundlePackageType</key> | ||
<string>FMWK</string> | ||
<key>CFBundleShortVersionString</key> | ||
<string>1.0</string> | ||
<key>CFBundleSignature</key> | ||
<string>????</string> | ||
<key>CFBundleVersion</key> | ||
<string>$(CURRENT_PROJECT_VERSION)</string> | ||
<key>NSHumanReadableCopyright</key> | ||
<string>Copyright © 2015 TypeLift. All rights reserved.</string> | ||
<key>NSPrincipalClass</key> | ||
<string></string> | ||
</dict> | ||
</plist> |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
// | ||
// Iso.swift | ||
// swiftz | ||
// | ||
// Created by Alexander Ronald Altman on 7/22/14. | ||
// Copyright (c) 2015 TypeLift. All rights reserved. | ||
// | ||
|
||
/// Captures an isomorphism between S and A. | ||
/// | ||
/// :param: S The source of the Iso heading right | ||
/// :param: T The target of the Iso heading left | ||
/// :param: A The source of the Iso heading right | ||
/// :param: B The target of the Iso heading left | ||
public struct Iso<S, T, A, B> { | ||
public let get : S -> A | ||
public let inject : B -> T | ||
|
||
/// Builds an Iso from a pair of inverse functions. | ||
public init(get : S -> A, inject : B -> T) { | ||
self.get = get | ||
self.inject = inject | ||
} | ||
|
||
/// Runs a value of type `S` along both parts of the Iso. | ||
public func modify(v : S, _ f : A -> B) -> T { | ||
return inject(f(get(v))) | ||
} | ||
|
||
/// Composes an `Iso` with the receiver. | ||
public func compose<I, J>(i2 : Iso<A, B, I, J>) -> Iso<S, T, I, J> { | ||
return self • i2 | ||
} | ||
|
||
/// Converts an Iso to a Lens. | ||
public var asLens : Lens<S, T, A, B> { | ||
return Lens { s in IxStore(self.get(s)) { self.inject($0) } } | ||
} | ||
|
||
/// Converts an Iso to a Prism with a getter that always succeeds.. | ||
public var asPrism : Prism<S, T, A, B> { | ||
return Prism(tryGet: { .Some(self.get($0)) }, inject: inject) | ||
} | ||
} | ||
|
||
/// The identity isomorphism. | ||
public func identity<S, T>() -> Iso<S, T, S, T> { | ||
return Iso(get: identity, inject: identity) | ||
} | ||
|
||
/// Compose isomorphisms. | ||
public func • <S, T, I, J, A, B>(i1 : Iso<S, T, I, J>, i2 : Iso<I, J, A, B>) -> Iso<S, T, A, B> { | ||
return Iso(get: i2.get • i1.get, inject: i1.inject • i2.inject) | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
// | ||
// IxCont.swift | ||
// swiftz | ||
// | ||
// Created by Alexander Ronald Altman on 6/10/14. | ||
// Copyright (c) 2015 TypeLift. All rights reserved. | ||
// | ||
|
||
/// `IxCont` is the Continuation Monad indexed by a result type `R`, an immediate output type `O` | ||
/// and a value `A`. | ||
public struct IxCont<R, O, A> { | ||
/// Lowers an `IxCont` to an indexed continuation function. | ||
public let run : (A -> O) -> R | ||
|
||
/// Lifts an indexed continuation function into an `IxCont`. | ||
public init(_ run : (A -> O) -> R) { | ||
self.run = run | ||
} | ||
|
||
/// Applies a function that transforms the input value of the continuation function. | ||
public func map<B>(f : A -> B) -> IxCont<R, O, B> { | ||
return f <^> self | ||
} | ||
|
||
/// Applies a function that transforms the final output value of the continuation function. | ||
public func imap<S>(f : R -> S) -> IxCont<S, O, A> { | ||
return f <^^> self | ||
} | ||
|
||
/// Applies a function that transforms the immediate output value of the continuation function. | ||
public func contramap<N>(f : N -> O) -> IxCont<R, N, A> { | ||
return f <!> self | ||
} | ||
|
||
/// Composes two continuation functions by applying the final result of the second to the | ||
/// immediate value of the first then running both continuations in series. | ||
public func ap<E, B>(f : IxCont<E, R, A -> B>) -> IxCont<E, O, B> { | ||
return f <*> self | ||
} | ||
|
||
/// Fits the receiver together with a second continuation and runs them in series. | ||
public func flatMap<E, B>(f : A -> IxCont<O, E, B>) -> IxCont<R, E, B> { | ||
return self >>- f | ||
} | ||
} | ||
|
||
public func run<R, O>(a : IxCont<R, O, O>) -> R { | ||
return a.run(identity) | ||
} | ||
|
||
public func pure<R, A>(x : A) -> IxCont<R, R, A> { | ||
return IxCont { $0(x) } | ||
} | ||
|
||
public func <^> <R, O, A, B>(f : A -> B, a: IxCont<R, O, A>) -> IxCont<R, O, B> { | ||
return IxCont { k in a.run { k(f($0)) } } | ||
} | ||
|
||
public func <^^> <R, S, O, A>(f : R -> S, a: IxCont<R, O, A>) -> IxCont<S, O, A> { | ||
return IxCont { f(a.run($0)) } | ||
} | ||
|
||
public func <!> <R, N, O, A>(f : N -> O, a: IxCont<R, O, A>) -> IxCont<R, N, A> { | ||
return IxCont { k in a.run { f(k($0)) } } | ||
} | ||
|
||
public func <*> <R, I, O, A, B>(f : IxCont<R, I, A -> B>, a: IxCont<I, O, A>) -> IxCont<R, O, B> { | ||
return IxCont { k in f.run { g in a.run { k(g($0)) } } } | ||
} | ||
|
||
public func >>- <R, I, O, A, B>(a : IxCont<R, I, A>, f: A -> IxCont<I, O, B>) -> IxCont<R, O, B> { | ||
return IxCont { k in a.run { f($0).run(k) } } | ||
} | ||
|
||
public func join<R, I, O, A>(a : IxCont<R, I, IxCont<I, O, A>>) -> IxCont<R, O, A> { | ||
return IxCont { k in a.run { $0.run(k) } } | ||
} | ||
|
||
public func shift<R, I, J, O, A>(f : (A -> IxCont<I, I, O>) -> IxCont<R, J, J>) -> IxCont<R, O, A> { | ||
return IxCont { k in run(f { pure(k($0)) }) } | ||
} | ||
|
||
public func reset<R, O, A>(a : IxCont<A, O, O>) -> IxCont<R, R, A> { | ||
return pure(run(a)) | ||
} | ||
|
||
public func callCC<R, O, A, B>(f : (A -> IxCont<O, O, B>) -> IxCont<R, O, A>) -> IxCont<R, O, A> { | ||
return IxCont { k in (f { x in IxCont { _ in k(x) } }).run(k) } | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
// | ||
// IxMultiStore.swift | ||
// swiftz | ||
// | ||
// Created by Alexander Ronald Altman on 8/4/14. | ||
// Copyright (c) 2015 TypeLift. All rights reserved. | ||
// | ||
|
||
/// The Store Comonad Transformer indexed by a position type `O` and the ArrayZipper Comonad. | ||
public struct IxMultiStore<O, I, A> { | ||
/// The current position of the receiver. | ||
let pos : O | ||
|
||
/// Retrieves a zipper that focuses on functions that retrieve values at index I. | ||
let set : ArrayZipper<I -> A> | ||
|
||
public init(_ pos: O, _ set: ArrayZipper<I -> A>) { | ||
self.pos = pos | ||
self.set = set | ||
} | ||
|
||
/// Applies a function to the retrieval of values. | ||
public func map<B>(f : A -> B) -> IxMultiStore<O, I, B> { | ||
return f <^> self | ||
} | ||
|
||
/// Applies a function to the position indexes that can be focused on by the underlying zipper. | ||
public func imap<P>(f : O -> P) -> IxMultiStore<P, I, A> { | ||
return f <^^> self | ||
} | ||
|
||
/// Applies a function to the retrieval indexes of the underlying zipper. | ||
public func contramap<H>(f : H -> I) -> IxMultiStore<O, H, A> { | ||
return f <!> self | ||
} | ||
|
||
/// Returns an `IxStore` that retrieves an `IxStore` for every index in the receiver. | ||
public func duplicate<J>() -> IxMultiStore<O, J, IxMultiStore<J, I, A>> { | ||
return IxMultiStore<O, J, IxMultiStore<J, I, A>>(pos, set ->> { g in { IxMultiStore<J, I, A>($0, g) } }) | ||
} | ||
|
||
/// Extends the context of the store with a function that retrieves values from another store | ||
/// indexed by a different position. | ||
public func extend<E, B>(f : IxMultiStore<E, I, A> -> B) -> IxMultiStore<O, E, B> { | ||
return self ->> f | ||
} | ||
|
||
/// Extracts a zipper that focuses on all values at a given index. | ||
public func put(x : I) -> ArrayZipper<A> { | ||
return { $0(x) } <^> set | ||
} | ||
|
||
/// Extracts a zipper that focuses on all values at an index given by applying a function to the | ||
/// receiver's position index. | ||
public func puts(f : O -> I) -> ArrayZipper<A> { | ||
return put(f(pos)) | ||
} | ||
|
||
/// Extracts the first focused value from the store at a given index. | ||
public func peek(x : I) -> A { | ||
return put(x).extract() | ||
} | ||
|
||
/// Extracts the first focused value from the store at an index given by applying a function to | ||
/// the receiver's position index. | ||
public func peeks(f : O -> I) -> A { | ||
return peek(f(pos)) | ||
} | ||
|
||
/// Returns a new `IxMultiStore` with its position index set to the given value. | ||
public func seek<P>(x : P) -> IxMultiStore<P, I, A> { | ||
return IxMultiStore<P, I, A>(x, set) | ||
} | ||
|
||
/// Returns a new `IxMultiStore` with its position index set to the result of applying the given | ||
/// function to the current position index. | ||
public func seeks<P>(f : O -> P) -> IxMultiStore<P, I, A> { | ||
return IxMultiStore<P, I, A>(f(pos), set) | ||
} | ||
} | ||
|
||
public func extract<I, A>(a : IxMultiStore<I, I, A>) -> A { | ||
return a.set.extract()(a.pos) | ||
} | ||
|
||
public func <^> <O, I, A, B>(f : A -> B, a : IxMultiStore<O, I, A>) -> IxMultiStore<O, I, B> { | ||
return IxMultiStore(a.pos, { g in { f(g($0)) } } <^> a.set) | ||
} | ||
|
||
public func<^^><O, P, I, A>(f : O -> P, a : IxMultiStore<O, I, A>) -> IxMultiStore<P, I, A> { | ||
return IxMultiStore(f(a.pos), a.set) | ||
} | ||
|
||
public func <!> <O, H, I, A>(f : H -> I, a : IxMultiStore<O, I, A>) -> IxMultiStore<O, H, A> { | ||
return IxMultiStore(a.pos, { $0 • f } <^> a.set) | ||
} | ||
|
||
public func ->> <O, J, I, A, B>(a : IxMultiStore<O, I, A>, f : IxMultiStore<J, I, A> -> B) -> IxMultiStore<O, J, B> { | ||
return IxMultiStore(a.pos, a.set ->> { g in { f(IxMultiStore($0, g)) } }) | ||
} | ||
|
||
public func lower<I, A>(a : IxMultiStore<I, I, A>) -> ArrayZipper<A> { | ||
return { $0(a.pos) } <^> a.set | ||
} |
Oops, something went wrong.