I've got two classes which inherit from a generic class.
class Parser<I: CollectionType, T> {
func parse(ts: I) -> [(T, I)] { return [] }
func parse_all(ts: I) -> [(T, I)] {
return parse(ts).filter { isEmpty($0.1) }
}
}
class CharParser<I: CollectionType, T> : Parser<[Character], Character> {
let c: Character
init(c: Character) { self.c = c }
override func parse(ts: [Character]) -> [(Character, [Character])] {
println(ts)
return ts[0] == c ? [(ts[0], Array(ts[1..<ts.count]))] : []
}
}
class AltParser<I: CollectionType, T> : Parser<I, T> {
let p: Parser<I, T>
let q: Parser<I, T>
init(p: Parser<I, T>, q: Parser<I,T>) {
self.p = p
self.q = q
}
override func parse(ts: I) -> [(T, I)] {
println(ts)
return p.parse(ts) + q.parse(ts)
}
}
class SeqParser<I: CollectionType, T, S>: Parser<I, (T, S)> {
let p: Parser<I, T>, q: Parser<I,S>
init(p: Parser<I, T>, q: Parser<I,S>) { self.p = p; self.q = q }
override func parse(ts: I) -> [((T, S), I)] {
var acc = [((T, S), I)]()
for (head1, tail1) in p.parse(ts) {
for (head2, tail2) in q.parse(tail1) {
acc += [((head1, head2), tail2)]
}
}
return acc
}
}
Calling
let x = CharParser<[Character], Character>(c: "a")
x.parse(Array("a"))
works fine, however trying to call it through the AltParser causes an EXC_BAD_ACCESS
let x2 = CharParser<[Character], Character>(c: "b")
let y = AltParser(p: x, q: x2)
let z = y.parse(Array("a"))
Is this a compiler bug or am I misunderstanding generics?
Okay, having failed completely to show that you can't do this, now I'm going to try to show that you can do it. Here's a heavily simplified version of your code that I believe works (at least it compiles and isn't crashing):
I eliminated everything that seemed superfluous to the example. I turned the Character into a String because I find Character confusing. I removed
parse_all
and the second propertyq
because you weren't using them for anything. Most significant, I removed the entire CollectionType from the generic and replaced it with an explicit array everywhere; that was because the CollectionType was giving me trouble compiling. I was frustrated, in particular, when I still had the CollectionType in the generic, by an inability to find a way to specify it is a collection of T; it seemed to me somehow crucial that this should be made clear. That is one reason why I removed it and replaced it with an explicit array of T. But perhaps I stumbled into something useful, because the code does seem to run now.Go ahead and pick it apart...!