 	}
 }
 
-extension ArrowOf : CustomReflectable {
-	public func customMirror() -> Mirror {
+extension ArrowOfImpl : CustomReflectable {
+	func customMirror() -> Mirror {
 		return Mirror(self, children: [
 			"types": "\(T.self) -> \(U.self)",
 			"currentMap": self.table,

	}
}

/// Generates two isomorphic Swift function from T to U and back again.
public final class IsoOf<T : protocol<Hashable, CoArbitrary, Arbitrary>, U : protocol<Equatable, CoArbitrary, Arbitrary>> : Arbitrary, CustomStringConvertible {
	private var table : Dictionary<T, U>
	private var embed : T -> U
	private var project : U -> T

	public var getTo : T -> U {
		return embed
	}

	public var getFrom : U -> T {
		return project
	}

	private init (_ table : Dictionary<T, U>, _ embed : (T -> U), _ project : (U -> T)) {
		self.table = table
		self.embed = embed
		self.project = project
	}

	public convenience init(_ embed : (T -> U), _ project : (U -> T)) {
		self.init(Dictionary(), { (_ : T) -> U in return undefined() }, { (_ : U) -> T in return undefined() })

		self.embed = { [weak self] t in

		}
	}

	var description : String {
		return "IsoOf<\(T.self) -> \(U.self), \(U.self) -> \(T.self)>"
	}

	static var arbitrary : Gen<IsoOfImpl<T, U>> {
		return Gen<(T -> U, U -> T)>.zip(promote({ a in
			return T.coarbitrary(a)(U.arbitrary)
		}), promote({ a in
			return U.coarbitrary(a)(T.arbitrary)
		})).fmap { IsoOfImpl($0, $1) }
	}

	static func shrink(f : IsoOfImpl<T, U>) -> [IsoOfImpl<T, U>] {
		return f.table.flatMap { (x, y) in
			return Zip2Sequence(T.shrink(x), U.shrink(y)).map({ (y1 , y2) -> IsoOfImpl<T, U> in
				return IsoOfImpl<T, U>({ (z : T) -> U in
					if x == z {
						return y2
					}
					return f.embed(z)
				}, { (z : U) -> T in
						if y == z {
							return y1
						}
						return f.project(z)
				})
			})
		}
	}
}

extension IsoOfImpl : CustomReflectable {
	func customMirror() -> Mirror {
		return Mirror(self, children: [
			"embed": "\(T.self) -> \(U.self)",
			"project": "\(U.self) -> \(T.self)",
