Search Haskell Channel Logs

Wednesday, February 22, 2017

#haskell channel featuring phadej, ph88^, MarcelineVQ, merijn, polux,

polux 2017-02-21 23:21:13
I don't think you can tell by looking at the type
ph88^ 2017-02-21 23:21:23
ya actually i was thinking the same thing .. when there are applicative and monad instances for both then you can't tell from the type i think
ph88^ 2017-02-21 23:21:49
would need to inspect it somehow after ghc did it's heuristics work on it
polux 2017-02-21 23:22:41
There's always the possibility of having an intermediate datatype that only has an Applicative instance, and then you interpret this datatype into a Parser
polux 2017-02-21 23:23:05
but that will probably incur some overhead
polux 2017-02-21 23:23:14
not to mention boilerplate
ph88^ 2017-02-21 23:23:37
what kind of overhead are you talking about ?
polux 2017-02-21 23:24:28
Let assume you define some datatype data MyParser a where FMap :: (a -> b) -> MyParser a -> MyParser b ...
polux 2017-02-21 23:24:51
then you only declare an Applicative instance for MyParser
polux 2017-02-21 23:24:56
but not a Monad one
polux 2017-02-21 23:25:12
then you annotate your applicative do expression to have type "MyParser Foo"
polux 2017-02-21 23:25:24
if that typechecks you'll know there is no bind
polux 2017-02-21 23:25:36
then you write a function interpret :: MyParser a -> Parser a
polux 2017-02-21 23:26:10
the overhead I was talking about is this MyParser constructors + the cost of interpreting them
phadej 2017-02-21 23:26:52
polux: you can use http://hackage.haskell.org/package/free-4.12.4/docs/Control-Alternative-Free.html
phadej 2017-02-21 23:27:00
so not so much boilerplate
ph88^ 2017-02-21 23:27:12
i don't really understand it
phadej 2017-02-21 23:27:35
and I'm quite sure that inliner will be able to remove intermediate 'Alt' all-together (but there is no guarantee, that's unfortunate indeed)
polux 2017-02-21 23:28:59
ph88^: what I was proposing and what phadej is suggesting is that instead of buiding an expression of type "Parser Foo" with your do expression, you instead build a tree that represents that expression, and you make sure that tree has no monad instance
polux 2017-02-21 23:29:08
then you translate that tree into a Parser Foo
polux 2017-02-21 23:29:21
to recover the parser you wanted to express in the first place
polux 2017-02-21 23:29:44
the whole point of this intermediate tree is to ensure that there is no bind
ph88^ 2017-02-21 23:29:55
ooh like that
ph88^ 2017-02-21 23:31:42
that made me look if there is already an applicative parser .. looks that there is https://hackage.haskell.org/package/applicative-parsec how does applicative give you those extra abilities mentioned: grammar analysis and validation tools
ph88^ 2017-02-21 23:32:07
some things that you can do with applicative that you can't do with monad so that this thing can do grammar analysis ?
polux 2017-02-21 23:32:58
ph88^: let's say it that way: if there is a bind, even bind is a constructor, you end up with a grammar of the form Bind and you can't "inspect" , it's a black box
polux 2017-02-21 23:33:45
with applicative the grammars you can express are less expressive (only context-free grammars) but you gain static analysis power over the grammar
ph88^ 2017-02-21 23:34:17
polux, actually to think about what you suggest i don't think it will be possible because i need to carry around a symbol table in State .. so i can not force all the rules to be applicative. I thought that ApplicativeDo could avoid using monad when not needed (for example when not reading or writing to State) ..
polux 2017-02-21 23:35:23
State is applicative too, the only thing you must not do in order to be applicative is things of the form do { x <- e; case x of p1 -> e1 | p2 -> e2 }
ph88^ 2017-02-21 23:35:27
polux, how can i do the inspection with applicative which can't be done with monad ?
polux 2017-02-21 23:35:29
i.e., inspect intermediate results
ph88^ 2017-02-21 23:36:31
those are constructors ?
ph88^ 2017-02-21 23:36:33
o_O
merijn 2017-02-21 23:36:41
ph88^: Monad can do everything Applicative can, but not all Applicatives have corresponding monads
polux 2017-02-21 23:36:43
you can decide to make them constuctors
polux 2017-02-21 23:36:58
for your particular datatype and applicative instance
ph88^ 2017-02-21 23:37:07
so <$> and <*> can become data constructors ?
polux 2017-02-21 23:37:10
yes
polux 2017-02-21 23:37:22
>>= can also become one, it's just not as useful for static analysis
MarcelineVQ 2017-02-21 23:37:27
could you elaborate on what you mean by gaining static analysys power?
merijn 2017-02-21 23:38:01
MarcelineVQ: <*> has an applicative on either side, whereas >>= only does on one side
polux 2017-02-21 23:38:43
it depends on the domain, but for grammars that might mean doing what YACC does on the grammar for instance, for Haxl it means being able to batch requests
ph88^ 2017-02-21 23:39:02
polux, when you build the shape of the computation are you only suppose to use <*> ? and then when you want to execute your computation use <$> ? or how can you do inspection before you execute ?
polux 2017-02-21 23:39:40
ph88^: you can use both, actually if you have pure, f <$> x is just pure f <*> x
polux 2017-02-21 23:39:55
so you just need a constructor for pure and one for <*>
ph88^ 2017-02-21 23:41:37
so it's pure that finally runs the builded computation ?
polux 2017-02-21 23:41:50
ah no, sorry, misunderstood your question
polux 2017-02-21 23:41:54
it's up to you then to run it