5 ms·
I don't mean to be anti-intellectual. But as someone who doesn't know much Haskell and likes to hand roll a precedence climber, my reaction to this is "so what?
by bruce343434 3y ago
I don't mean to be anti-intellectual. But as someone who doesn't know much Haskell and likes to hand roll a precedence climber, my reaction to this is "so what?". But really, what are the implications of this? What does this mean for the code that does the actual parsing, how does this transform how you specify the rules of the grammar in code?
- contravariant 3y agoWell it means that if you've got a parser that returns 'a' and a function from 'a' to 'b' then you can make a parser that returns 'b'. And if you've also got a function from 'b' to 'c' then function composition basically does what you'd expect. Which, you know, sounds extremely trivial. The applicative part is a bit more interesting, it means if you've got a parser that returns a function 'a -> b' and a parser that returns an input 'a' for that function then you can make a parser that returns 'b'. This would have been interesting in general categories, but in Haskell function types with currying and application isn't really a remarkable feature so preserving this structure becomes more of a necessity than an interesting feature.
- marcosdumay 3y agoWell, I've had to use parsers in other languages that weren't pure or where one couldn't just translate the "Result a" equivalent to "Result b". That always lead to a bunch of annoyingly error-prone boilerplate. But yeah, that's it. I'd say that half of the Haskell's value is avoiding a bunch of annoyingly error-prone boilerplate... everywhere and recursively.
- contravariant 3y agoYeah I suppose that is the other side of the coin. Knowing about functors makes it easier to intuit what utilitu functions to write to avoid boilerplate. But sometimes the 'mysticism' gets in the way, this article spends a lot of words on technicalities but very little on the intuition that this should be fairly trivially true. This might make sense in the context for which this article is written, but why this article is on the front page of HN I don't understand.
- headbee 3y agoIt opens up a huge toolbox of tools that work with Functors and Applicative to make parsing easier, and proves that using those tools will work predictably.
- 082349872349872 3y agoAs the last sentence might imply, it's not meant to be so much of value for building parsers as for proving things about the parsers as-built...
- itishappy 3y agoIt means you can map over parsers. For example, if you have a parser that returns numbers formatted as strings you can turn it directly into a parser that returns a number.
- thosakwe 3y agoI learned Haskell this year. After reading this article, the conclusion I drew was, "Cool, so I can `fmap` over my parser now and transform what I parse using functions." To answer your other questions: I'm not sure it means much for the code that does the actual parsing, nor how you specify the grammar's rules, it's more about being able to transform the output using functions. If your static analyzer is a function, you could now write `fmap staticAnalyzer myParser`.
- Joker_vD 3y ago> about being able to transform the output using functions. Can't one always use functions to transform other functions' outputs? > If your static analyzer is a function, you could now write `fmap staticAnalyzer myParser`. rolls eyes def compile(text): ast = parse(text) ir, symtable = static_analyze(ast) asm = lower(ir, symtable) return assemble(asm) Ability to write that in the point-free style is really not that important, IMHO.
- thosakwe 3y agoYes, but if it we're talking about parser monads, then usually you can't apply a function directly to a parser's result without either: 1. Being within the same monad. For example, you can `bind` a `Parser a` to a function only if it returns `Parser b`. 2. Performing an actual action and breaking it out of its monad. For example, if you're using the Parsec library, and you have a `Parser Int`, you can't get to that int without using a function like `parse`, performs the actual action of parsing input text. With a functor, you can compose a `Parser a` within an `a -> b` function, instead of having to return `Parser b` in your function. So if you have a `Parser Int`, and you want to turn it into a parser that multiplies its parsed input by 2, you can write `fmap (*2) myParser`, instead of having to write `myParser >>= \a -> return (a * 2)`. Parsers being functors means it's easier to compose them with other things, without having to actually perform the parse until you need to.
- viraptor 3y agoI don't get the last part of the comment. `myParser >>= \a -> return (a * 2)` doesn't have to parse immediately, right? You could push that function at the end of a list and only apply it during `parse` anyway.
- ng12 3y agoAs someone who works primary in a functional language I'm pretty convinced that most of these types of things are elegant solutions to self-created problems.
- danielvaughn 3y agotbh this is how I feel about most tech. I was in front-end dev for many years and a lot of the framework features felt like that. Now I'm doing back-end devops stuff and Helm/K8s/Terraform really feel like that. Everywhere you look, it's nothing but hammer factory factory factories.
- jerf 3y agoIn general, if your reaction to finally understanding "functors" is "so what?", there's a reasonably good chance that means you've actually understood them: https://jerf.org/iri/post/2958/ https://jerf.org/iri/post/2958/ The useful thing about functors isn't that they are particularly complicated, it is that they are a useful interface to be able to write things generically over. It's very similar to iterators. Being able to present items out of some collection one at a time is "so what?" It is not interesting on its own. But having a common interface over them allows for a lot of good code to be written that you can't write in a language that lacks them, and have to one-off ad-hoc all the time. That a Parser is a Functor means you can apply all the functor tools in writing them. This is one of the appeals of parser combinators, which is again not that they are some sort of brilliant insight on their own, but that they work well with the generalized tools rather than needing specific implementations of them.
- deleted 3y ago[deleted]
- 4death4 3y agoIf your reaction to iterators is “so what?” then I would say you fundamentally don’t understand computation. Asking “so what?” about iterators has plenty of useful answers that will aide you in programming. The same is not really true about functors.
- jerf 3y agoThe linked article goes into detail about what I mean about that, but what I mean is that some of these concepts have a lot of mystery around them that are not deserved. Many people penetrate this mystery and then wonder what the deal was with the mystery. For these particular concepts, that's generally a good sign. Iterators are important... but they are not conceptually complicated. They're just a way of getting a "next element". Behind that may be a lot of complexity for some particular iterator, but that complexity should be accounted to the implementation, not the concept of iterator.
- 3y ago