Skip to content

Instantly share code, notes, and snippets.

@robrix
Last active August 29, 2015 14:15
Show Gist options
  • Save robrix/5d3b7268b661630cc6dc to your computer and use it in GitHub Desktop.
Save robrix/5d3b7268b661630cc6dc to your computer and use it in GitHub Desktop.
The sum is more than the hole of its parts
a b a && b
👎 👎 👎
👍 👎 👎
👎 👍 👎
👍 👍 👍
let error: Error?
switch result {
case let Left(e):
error = e
default:
error = nil
}
if let error = error {
return didFailWithError(error)
}
var left: T? {
switch self {
case Left(value):
return value
default:
return nil
}
}
var right: U? {
switch self {
case Right(value):
return value
default:
return nil
}
}
if let error = result.left {
return didFailWithError(error)
}
if let error = result.left {
return didFailWithError(error)
} else if let success = result.right {
return didSucceedWithValue(success)
}
switch result {
case let Left(error):
return didFailWithError(error)
case let Right(success):
return didSucceedWithValue(success)
}
func either<Result>(ifLeft: T -> Result, _ ifRight: U -> Result) -> Result
func either<Result>(ifLeft: T -> Result, _ ifRight: U -> Result) -> Result {
switch self {
case let Left(x):
return ifLeft(x)
case let Right(y):
return ifRight(y)
}
}
var left: T? {
return either({ x in x }, { _ in nil })
}
var right: T? {
return either({ _ in nil }, { x in x })
}
return result.either(didFailWithError, didSucceedWithValue)
enum Either<T, U> {
case Left(Box<T>)
case Right(Box<U>)
}
(Bool, Bool) -> Bool
enum Type {
case Base(BaseType)
case Variable(Manifold.Variable)
case Function(Box<Type>, Box<Type>)
case Universal(Set<Manifold.Variable>, Box<Type>)
public func analysis<T>(#ifBase: BaseType -> T, ifVariable: Manifold.Variable -> T, ifFunction: (Type, Type) -> T, ifUniversal: (Set<Manifold.Variable>, Type) -> T) -> T {
switch self {
case let Base(t):
return ifBase(t)
case let Variable(v):
return ifVariable(v)
case let Function(t1, t2):
return ifFunction(t1.value, t2.value)
case let Universal(a, t):
return ifUniversal(a, t.value)
}
}
}
public func combine<A, B>(a: Either<Error, A>, b: Either<Error, B>) -> Either<Error, (A, B)> {
return a.either(
{ (a: Error) in b.either(
{ Either.left(a + $0) },
const(Either.left(a))) },
{ (a: A) in b.either(
Either.left,
{ Either.right(a, $0) }) })
}
enum Bool {
case True
case False
}
public func == (left: Type, right: Type) -> Bool {
switch (left, right) {
case let (.Base(b1), .Base(b2)):
return b1 == b2
case let (.Variable(x), .Variable(y)):
return x == y
case let (.Function(x1, x2), .Function(y1, y2)):
return x1.value == y1.value && x2.value == y2.value
case let (.Universal(a1, t1), .Universal(a2, t2)):
return a1 == a2 && t1 == t2
default:
return false
}
}
private func pairwise(t1: Type, t2: Type, f: (Type, Type) -> ()) {
t1.analysis(
ifBase: { _ in
t2.analysis(
ifBase: { _ in f(t1, t2) },
ifVariable: const(()),
ifFunction: const(()),
ifUniversal: const(()))
},
ifVariable: { _ in
t2.analysis(
ifBase: const(()),
ifVariable: { _ in f(t1, t2) },
ifFunction: const(()),
ifUniversal: const(()))
},
ifFunction: { t11, t12 in
t2.analysis(
ifBase: const(()),
ifVariable: const(()),
ifFunction: { t21, t22 in
f(t1, t2)
f(t11, t21)
f(t12, t22)
},
ifUniversal: const(()))
},
ifUniversal: { _, _ in
t2.analysis(
ifBase: const(()),
ifVariable: const(()),
ifFunction: const(()),
ifUniversal: { _, _ in
f(t1, t2)
})
})
}
t1.analysis(
ifBase: { _ in t2.analysis(ifBase: { _ in f(t1, t2) }) },
ifVariable: { _ in t2.analysis(ifVariable: { _ in f(t1, t2) })},
…)
public var base: BaseType? {
return analysis(
ifBase: id,
ifVariable: const(nil),
ifFunction: const(nil),
ifUniversal: const(nil))
}
public var variable: Manifold.Variable? {
return analysis(
ifBase: const(nil),
ifVariable: id,
ifFunction: const(nil),
ifUniversal: const(nil))
}
public var function: (Type, Type)? {
return analysis(
ifBase: const(nil),
ifVariable: const(nil),
ifFunction: id,
ifUniversal: const(nil))
}
public var universal: (Set<Manifold.Variable>, Type)? {
return analysis(
ifBase: const(nil),
ifVariable: const(nil),
ifFunction: const(nil),
ifUniversal: id)
}
func &&& <T, U> (left: T?, right: U?) -> (T, U)? {
return left.map { l in right.map { r in (l, r) } } ?? nil
}
public func combine<A, B>(a: Either<Error, A>, b: Either<Error, B>) -> Either<Error, (A, B)> {
return
(a.right &&& b.right).map(Either.right)
?? (a.left &&& b.left).map(+).map(Either.left)
?? a.left.map(Either.left)
?? b.left.map(Either.left)!
}
private func structural<T>(t1: Type, t2: Type, f: (Type, Type) -> T) -> T? {
return
(t1.base.map(const(t1)) &&& t2.base.map(const(t2))).map(f)
?? (t1.variable.map(const(t1)) &&& t2.variable.map(const(t2))).map(f)
?? (t1.function &&& t2.function).map { f($0.1, $1.1) }
?? (t1.universal.map(const(t1)) &&& t2.universal.map(const(t2))).map(f)
}
(Either<Error, T>, Either<Error, T>) -> Either<Error, T>
func && (a: Bool, b: Bool) -> Bool {
switch (a, b) {
case (false, true), (true, false), (false, false):
return false
case (true, true)
return true
}
}
func combine<T> (a: Either<Error, T>, b: Either<Error, T>) -> Either<Error, T> {
switch (a, b) {
case (.Left, .Right):
return a
case (.Right, .Left):
return b
case let (.Left(x), .Left(y)):
return .Left(failure(x, y))
case let (.Right(x), .Right(y)):
return .Right(success(x, y))
}
}
enum Error {
case Leaf(String)
case Branch([Error])
}
func failure(a: Error, b: Error) -> Error {
switch (a, b) {
case let (.Leaf, .Branch(errors)):
return .Branch([ a ] + errors)
case let (.Branch(errors), .Leaf):
return .Branch(errors + [ b ])
case let (.Leaf, .Leaf):
return .Branch([ a, b ])
case let (.Branch(errors1), .Branch(errors2)):
return .Branch(errors1 + errors2)
}
}
func combine<T> (a: Either<Error, T>, b: Either<Error, T>, success: (T, T) -> T) -> Either<Error, T>
func == <T: Equatable, U: Equatable> (a: Either<T, U>, b: Either<T, U>) -> Bool {
switch (a, b) {
case (.Left(x), .Left(y)):
return x == y
case (.Right(x), .Right(y)):
return x == y
default:
return false
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment