## Where communities thrive

• Join over 1.5M+ people
• Join over 100K+ communities
• Free without limits
##### Activity
Ryan Heins
@RyanHeins

Hello, I'm new here. I have a question about atto, and I already know the answer is traverse, but traverse doesn't seem to be defined. What I want is

val myParser: Parser[MyType] = ???

val myThings: ParseResult[List[MyType]] = List("thing1", "thing2").traverse(myParser.parse)

Since I have a list of strings to parse and not just a single string I can't get sequence to work for me.

Christopher Davenport
@ChristopherDavenport
Do you have cats.implicits._ in scope?
Ryan Heins
@RyanHeins
I do
Christopher Davenport
@ChristopherDavenport
Ah,m ParseResult only ofrms a functor, not an applicative.
Rob Norris
@tpolecat
yeah
Christopher Davenport
@ChristopherDavenport
Try, .traverse(a => myParser.parse(a).either)
Rob Norris
@tpolecat
yeah
@ List("1","2","3").traverse(int.parseOnly(_).either)
res4: Either[String, List[Int]] = Right(List(1, 2, 3))

@ List("1","woozle","3").traverse(int.parseOnly(_).either)
res5: Either[String, List[Int]] = Left("Failure reading:bigInt")
Ryan Heins
@RyanHeins
That worked, thanks!
Christopher Davenport
@ChristopherDavenport
Pure is easy, but Not sure how youd implement ap over Partials
Actually you do both in terms of partial that way you could feed.
def pure(a: A): ParseReseult[A] = Partial(k: String => Done(k, a))
def ap(ff: ParseResult[A => B], fa: ParseResult[A] ): ParseResult[B] = case (ff, fa) match {
case (e@Fail(_,_,_), _) => e
case (_, e@Fail(_,_,_) => e
case (Done(s1, f), Done(s2, a) => Done(???, f(a))
case (Partial(f1), _) => ???
case (_, Partial(_)) =>  ???
Christopher Davenport
@ChristopherDavenport
Thats tricky, I see why you went with functor
Wojtek Pituła
@Krever
Hey, did anyone of you have a need for a more generic version of atto, where parser abstract over input (so Parser[In, Out])?
Christopher Davenport
@ChristopherDavenport
I have one, gato-parsec. @Krever
Wojtek Pituła
@Krever
Of course you have @ChristopherDavenport , why haven't I checked :D Thanks a lot, will check it out.
Christopher Davenport
@ChristopherDavenport
It's pretty bare-bones, but you should be able to build off it
Wojtek Pituła
@Krever
You didn't want to migrate/have char/string/numbers-specific parsers there? Or it just needs to be done?
Billzabob
@Billzabob

Hello! I’m struggling and need some help here. I have a parser that runs forever and I can’t figure out why. First, the working code before the change:

val required = List("byr", "iyr", "eyr", "hgt", "hcl", "ecl", "pid")

val itemParser = take(3) <~ (char(':') ~ stringOf(noneOf(" \n")))
val passportParser = itemParser.sepBy(oneOf(" \n")).filter(keys => required.forall(keys.contains)) <~ (string("\n\n").void | endOfInput)
val passportsParser = passportParser.many1

val example =
"""ecl:gry pid:860033327 eyr:2020 hcl:#fffffd
byr:1937 iyr:2017 cid:147 hgt:183cm

ecl:gry pid:860033327 eyr:2020 hcl:#fffffd
byr:1937 iyr:2017 cid:147 hgt:183cm"""

println(passportsParser.parse(example).done)

This works fine and gives the expected result of Done(,NonEmptyList(List(ecl, pid, eyr, hcl, byr, iyr, cid, hgt), List(ecl, pid, eyr, hcl, byr, iyr, cid, hgt))).
However, if I add opt like so on the passportsParser: val passportsParser = opt(passportParser).many1, then it runs forever and complains about garbage collection.

Any idea why?

Rob Norris
@tpolecat
opt(p).many1 will run forever
because opt(p) never fails
Billzabob
@Billzabob
Shouldn’t it stop at the end of the input?
opt still consumes input right?
Hmmm I guess it wouldn’t acutally… Ok, thinking about it and it all makes sense now
Rob Norris
@tpolecat
cats-parse has Parser and Parser1 to make it harder to run into this problem
Billzabob
@Billzabob
Sorry, what is cats-parse? I can’t find anything on that
Rob Norris
@tpolecat
it's the first hit if you google it!
Billzabob
@Billzabob
🤦🏻‍♂️ I was looking in atto and cats. Thanks
TimmyC101
@TimmyC101
Good afternoon, all. I'm working on developing a parser for an iCalendar library, and wanted to verify that atto parser was fit for purpose. Specifically, I need to be able to parse strings in any order, and a variable number of times (0, once, multiple). Is atto sufficient for this, or is it fairly rigid in terms of ordering and frequency? If sufficient, directing me toward a similar use case would be much appreciated! Thank you.
Rob Norris
@tpolecat
Yes, it's fine for this but I would recommend you look at cats-parse. It's newer and simpler and much faster.
Atto isn't officially deprecated but it likely will be pretty soon.
TimmyC101
@TimmyC101
Rob, thank you so much for the prompt reply. I will look into cats-parse!
Rob Norris
@tpolecat
:+1:
Afsal Thaj
@afsalthaj

A great library, especially I was using the monoid addition of parser, whose internal implementation is |, and found to be useful in almost all places in our production code.
I was wondering, if there is a way to accumulate errors

val parser = list.map(_.parser).combineAll

Such that if all of the parsers in the list fails, I get a list of accumulated parser errors. May be that I am missing some part of the API.

I am using atto 0.7.0 version.
Afsal Thaj
@afsalthaj
@tpolecat Could you help me with this one? :)
Rob Norris
@tpolecat
Sorry I am out of town. I will be back on Monday.
Afsal Thaj
@afsalthaj
No worries. Thanks @tpolecat