Skip to content

Instantly share code, notes, and snippets.

@oisdk
Last active September 5, 2015 13:54
Show Gist options
  • Save oisdk/b2d923f34d9bef34c654 to your computer and use it in GitHub Desktop.
Save oisdk/b2d923f34d9bef34c654 to your computer and use it in GitHub Desktop.
protocol Nat {}
struct Zero : Nat {}
protocol NonZero: Nat { typealias Pred: Nat }
struct Succ<N : Nat> : NonZero { typealias Pred = N }
protocol _AnyTuple : CustomStringConvertible {
var tDesc: String { get }
var count: Int { get }
typealias Arity : Nat
}
struct EmptyTuple {}
extension EmptyTuple : _AnyTuple {
var description: String { return "()" }
var tDesc: String { return ")" }
var count: Int { return 0 }
typealias Arity = Zero
}
struct NonEmptyTuple<Element, Tail : _AnyTuple> { var (head, tail): (Element, Tail) }
extension NonEmptyTuple : _AnyTuple {
var count: Int { return tail.count + 1 }
var description: String {
return "(" + String(reflecting: head) + tail.tDesc
}
var tDesc: String {
return ", " + String(reflecting: head) + tail.tDesc
}
typealias Arity = Succ<Tail.Arity>
}
infix operator ⸒ { associativity right precedence 90 }
func ⸒<E, T:_AnyTuple>(lhs: E, rhs: T) -> NonEmptyTuple<E, T> {
return NonEmptyTuple(head: lhs, tail: rhs)
}
func ⸒<E, T>(lhs: E, rhs: T) -> NonEmptyTuple<E, NonEmptyTuple<T, EmptyTuple>> {
return NonEmptyTuple(head: lhs, tail: NonEmptyTuple(head: rhs, tail: EmptyTuple()))
}
typealias One = Succ<Zero>
typealias Two = Succ<One>
typealias Three = Succ<Two>
protocol Tuple : _AnyTuple {
typealias Head
typealias Tail : _AnyTuple
typealias Arity : NonZero
var head : Head { get }
var tail : Tail { get }
}
extension NonEmptyTuple : Tuple {}
(1 ⸒ 2.0 ⸒ "a" )
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment