 	}
 }
 
-/// 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)) {
+private final class IsoOfImpl<T : protocol<Hashable, CoArbitrary, Arbitrary>, U : protocol<Equatable, CoArbitrary, Arbitrary>> : Arbitrary, CustomStringConvertible {
+	var table : Dictionary<T, U>
+	var embed : T -> U
+	var project : U -> T
+
+	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)) {
+	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

		}
	}

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

	public static var arbitrary : Gen<IsoOf<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 { IsoOf($0, $1) }
	}

	public static func shrink(f : IsoOf<T, U>) -> [IsoOf<T, U>] {
		return f.table.flatMap { (x, y) in
			return Zip2Sequence(T.shrink(x), U.shrink(y)).map({ (y1 , y2) -> IsoOf<T, U> in
				return IsoOf<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 IsoOf : CustomReflectable {
	public func customMirror() -> Mirror {
		return Mirror(self, children: [
			"embed": "\(T.self) -> \(U.self)",
			"project": "\(U.self) -> \(T.self)",

		}
	}

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

	static var arbitrary : Gen<ArrowOfImpl<T, U>> {
		return ArrowOfImpl.init <^> promote { a in
			return T.coarbitrary(a)(U.arbitrary)
		}
	}

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