Skip to content

Instantly share code, notes, and snippets.

@chriseidhof
Created May 17, 2017 09:43
Show Gist options
  • Select an option

  • Save chriseidhof/f807be9afb525ee424c01fa0c2ca72d7 to your computer and use it in GitHub Desktop.

Select an option

Save chriseidhof/f807be9afb525ee424c01fa0c2ca72d7 to your computer and use it in GitHub Desktop.
existentials
indirect enum Parser<A> {
case nilP(v: A?)
case altP(p1: Parser<A>, p2: Parser<A>)
case _bindP(p1: Parser<Any>, cont: (Any) -> Parser<A>) // don't use directly
func map<B>(_ f: @escaping (A) -> B) -> Parser<B> {
switch self {
case let .nilP(v: x): return .nilP(v: x.map(f))
case let .altP(p1: p1, p2: p2): return .altP(p1: p1.map(f), p2: p2.map(f))
case let ._bindP(p1: p1, cont: g): return Parser<B>._bindP(p1: p1, cont: { (x: Any) -> Parser<B> in g(x).map(f) })
}
}
static func bind<I>(p1: Parser<I>, p2: @escaping (I) -> Parser<A>) -> Parser<A> {
return ._bindP(p1: p1.map { $0 }, cont: { (x: Any) -> Parser<A> in
let value = x as! I
return p2(value)
})
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment