struct RangedTerm { typealias Term = Cofree)> let term: Term } struct UnannotatedTerm { typealias Term = Cofree let term: Term var source: String { return term.cata { switch $0 { case let .Leaf(s): return s case let .Indexed(s): return "[\n\t" + s.joinWithSeparator(",\n\t") + "\n]" case let .Keyed(s): return "{\n\t" + s.map { "\"\($0)\": \($1)" }.joinWithSeparator(",\n\t") + "\n}" } } } } extension UnannotatedTerm: Arbitrary { static var arbitrary: Gen { let leaf: Gen = String.arbitrary.fmap { Term((), .Leaf($0)) } let indexed: Gen = Gen.sized { n in Gen.choose((0, n)).bind { n in sequence((0.. = Gen.sized { n in Gen.choose((0, n)).bind { n in sequence((0..