package scalaz package std package util package parsing package combinator import scala.util.parsing.combinator trait Parsers { class ParsersW[P <: combinator.Parsers](val parser: P) { type Parser[A] = parser.Parser[A] def instance: Monad[Parser] = new Monad[Parser] { def point[A](a: => A): Parser[A] = parser.success(a) def bind[A, B](fa: Parser[A])(f: A => Parser[B]): Parser[B] = fa flatMap f } } // A few type gymnastics are required to target the path-dependent type // // The return type is Monad[p.type#Parser] // // This way seems to work without -Ydependent-method-types, yay! def parserMonad[P <: combinator.Parsers](p: P) = new ParsersW[P](p).instance /* Alternative that works fully implicitly at the expense of a cast. class ParsersW[P <: combinator.Parsers with Singleton] { type Parser[A] = P#Parser[A] object dummyParser extends combinator.Parsers def instance: Monad[Parser] = new Monad[Parser] { def pure[A](a: => A): Parser[A] = dummyParser.success(a).asInstanceOf[Parser[A]] // please look the other way! def bind[A, B](fa: Parser[A])(f: A => Parser[B]): Parser[B] = fa flatMap f } } // A few type gymnastics are required to target the path-dependent type // // The return type is Monad[p.type#Parser] // // This way seems to work without -Ydependent-method-types, yay! implicit def parserMonad[P <: combinator.Parsers with Singleton] = new ParsersW[P].instance */ } object parser extends Parsers