Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6722011
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 26, 20262026-05-26T09:23:48+00:00 2026-05-26T09:23:48+00:00

In this recent Stack Overflow question , the author wanted to change a list

  • 0

In this recent Stack Overflow question, the author wanted to change a list of parsers of some type into a parser that returns lists of that type. We can imagine doing this with Scalaz’s sequence for applicative functors:

import scala.util.parsing.combinator._

import scalaz._
import Scalaz._

object parser extends RegexParsers {
  val parsers = List(1, 2, 3).map(repN(_, """\d+""".r))
  def apply(s: String) = parseAll(parsers.sequence, s)
}

Here we take a list of three parsers that return lists of integers and turn it into a parser that returns lists of lists of integers. Unfortunately Scalaz doesn’t provide an Applicative instance for Parser, so this code doesn’t compile, but that’s easy to fix:

import scala.util.parsing.combinator._

import scalaz._
import Scalaz._

object parser extends RegexParsers {
  val parsers = List(1, 2, 3).map(repN(_, """\d+""".r))
  def apply(s: String) = parseAll(parsers.sequence, s)

  implicit def ParserPure: Pure[Parser] = new Pure[Parser] {
    def pure[A](a: => A) = success(a)
  }

  implicit def ParserFunctor: Functor[Parser] = new Functor[Parser] {
    def fmap[A, B](p: Parser[A], f: A => B) = p.map(f)
  }

  implicit def ParserBind: Bind[Parser] = new Bind[Parser] {
    def bind[A, B](p: Parser[A], f: A => Parser[B]) = p.flatMap(f)
  }
}

This works as expected: parser("1 2 3 4 5 6") gives us List(List(1), List(2, 3), List(4, 5, 6)), for example.

(I know I could just give an Apply instance, but the Bind instance is more concise.)

It would be nice not to have to do this every time we extend Parsers, but I’m not clear on how to get an Applicative instance for Parsers#Parser more generally. The following naive approach of course doesn’t work, since we need the instances of Parsers to be the same:

implicit def ParserBind: Bind[Parsers#Parser] = new Bind[Parsers#Parser] {
  def bind[A, B](p: Parsers#Parser[A], f: A => Parsers#Parser[B]) = p.flatMap(f)
}

It’s pretty clear to me that this should be possible, but I’m not comfortable enough with Scala’s type system to know how to go about it. Is there something simple that I’m missing?


In response to the answers below: I did try the -Ydependent-method-types route, and got this far:

implicit def ParserApplicative(g: Parsers): Applicative[g.Parser] = {
  val f = new Functor[g.Parser] {
    def fmap[A, B](parser: g.Parser[A], f: A => B) = parser.map(f)
  }

  val b = new Bind[g.Parser] {
    def bind[A, B](p: g.Parser[A], f: A => g.Parser[B]) = p.flatMap(f)
  }

  val p = new Pure[g.Parser] {
    def pure[A](a: => A) = g.success(a)
  }

  Applicative.applicative[g.Parser](p, FunctorBindApply[g.Parser](f, b))
}

The problem (as didierd points out) is that it’s unclear how to get the implicit to kick in. So this approach does work, but you have to add something like the following to your grammar:

implicit val applicative = ParserApplicative(this)

At that point the mixin approach is obviously much more attractive.

(As a side note: I expected to be able to write simply Applicative.applicative[g.Parser] above, but that gives an error saying the compiler can’t find an implicit value for the Pure[g.Parser]—even though one is sitting right next to it. So clearly there’s something different about the way implicits work for dependent method types.)


Thanks to retronym for pointing out a trick that accomplishes what I want here. I’ve abstracted the following from his code:

implicit def parserMonad[G <: Parsers with Singleton] =
  new Monad[({ type L[T] = G#Parser[T] })#L] {
    def pure[A](a: => A): G#Parser[A] = {
      object dummy extends Parsers
      dummy.success(a).asInstanceOf[G#Parser[A]]
    }

    def bind[A, B](p: G#Parser[A], f: (A) => G#Parser[B]): G#Parser[B] =
      p.flatMap(f)
  }

If you have this in scope, you get a monad instance for Parser in any object extending Parsers. It’s kind of cheating because of the cast, but still pretty neat.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-26T09:23:49+00:00Added an answer on May 26, 2026 at 9:23 am

    I usually add implicit extension to Parser in mixins for Parsers

    trait BindForParser extends Parsers {
      implicit def ParserBind = new Bind[Parser] {
        def bind[A,B](p: Parser[A], f: A => Parser[B]) = p flatMap f
      }
    }
    

    Then you just have to mix that in your grammar (Parsers), and as Parser instances are usually manipulated only inside Parsers, there are not much chances the mixin would be needed afterwards, when the grammar is done and you can no longer mix something in. In your example, you just do

    object parser extends Parsers with BindForParser
    

    On the more general question, whether it is possible to do it “from the outside”, the most direct way would probably be something like

    implicit def ParserBind(grammar: Parsers) = new Bind[grammar.Parser] {
      def bind[A,B](p: grammar.Parser[A], f: A => grammar.Parser[B]) = p flatMap f
    }
    

    But this is not allowed, a method parameter (here grammar) is not considered a stable identifier and so grammar.Parser is not allowed as a type. It is however possible with option -Xexperimental. But even then, I don’t see how the implicit would kick in when needed. What we want is an implicit Bind[grammar.Parser], and with the grammar parameter this is not what we have.

    So my answer would be it cannot be done, but I would not be that surprised if someone could come up with something.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

In a recent question on Stack Overflow , I asked how I might parse
This recent question about sorting randomly using C# got me thinking about the way
In this answer to a recent question , I was advised to be wary
This is very similar to another recent question: How can I return the current
There is another recent Project Euler question but I think this is a bit
Not sure if this is best suited to Programmers, Server Fault or Stack Overflow.
I've gone through various tutorials and Stack Overflow posts and understand that Selenium can
Recent conversations with colleagues have produced varying points of view on this matter. What
I'm running Mac OSX Snow Leopard, this problem is caused by a recent train
This might seem like a stupid question I admit. But I'm in a small

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.