is there a rule about operators that overrides normal layouting rules? it appears that the indent of that line must be larger than the parent layout (like in case of a nested do, it's the outer do's layout indent). it also only works for expression statements, not binders.
if someone can point me to documentation, that would be great
https://www.haskell.org/onlinereport/haskell2010/haskellch10.html#x17-17800010.3 provides algorithmic description of layout resolution - if you look at lines mentioning <n> (line fold), in your case they'll add } before the operator, because indent is lower than one set by do, and pop the <n>, because it's bigger than outer context
my question now is: what is the condition in the layout algorithm that detects that >>= closes the do instead of only starting a new statement? is it because the op is symbolic?
can anyone explain why this parses:
is there a rule about operators that overrides normal layouting rules? it appears that the indent of that line must be larger than the parent layout (like in case of a nested do, it's the outer do's layout indent). it also only works for expression statements, not binders.
if someone can point me to documentation, that would be great
https://www.haskell.org/onlinereport/haskell2010/haskellch10.html#x17-17800010.3 provides algorithmic description of layout resolution - if you look at lines mentioning
<n>
(line fold), in your case they'll add}
before the operator, because indent is lower than one set bydo
, and pop the<n>
, because it's bigger than outer contextOh, wait, I've now realized you mean line after that :sweat_smile:
ghc parser confirmed that in fact the whole do is the arg to the bind
I would have guessed this requires BlockArguments tbh
Okay, but how's
valid?
:grinning:
hahaha
Applicative (r->)
the first pure is const
it's
const pure 5
Ah, I see now :joy:
maybe we should assassinate that instance from the ghc codebase
while nobody is watching
now how to parse this:
whoever is using it can't be up to any good
(inspired by a file from HLS breaking my parser)
apparently it might be
(do pure 5) >>= f
Georgi Lyubenov // googleson78 said:
hacker in hoodie gif
image.png
indeed!
I would expect GHC to do
do (pure 5 >>= f)
because ofNonDecreasingIndentation
not in a layout
if you move the
>>=
one char to the right, it's like you wroteOh, it's for
{n}
, not<n>
, righthttps://giphy.com/gifs/theoffice-the-office-tv-frame-toby-vyTnNTrs3wqQ0UIvwE
We need
-Wimplicit-layout
in GHC, so than we can safely forget about it and write braces everywhere :sweat_smile:doesn't help if you want to parse other people's code!
or be more strict about what is allowed :sweat:
that will never happen :cry:
two spaces indent enforced everywhere. newline after layout open
Thing is though, we often write stuff that seems completely reasonable to humans but requires this flexibility, like
looks like it matches my rules
then
opens a layout, but no newline after it?right?
then
don't open no layoutonly
do
does for expressionsonly
let
,of
,where
,do
@Georgi Lyubenov // googleson78 what you see with newlines after tokens like
=
is indentation rule for surrounding layoutmy question now is: what is the condition in the layout algorithm that detects that
>>=
closes thedo
instead of only starting a new statement? is it because the op is symbolic?or are there more cases that cause this?
it can't be type-directed, right?
parse-error(>>=)
should be true, shouldn't it?huh
it expects expression, but gets some operator
that sucks
Yeah - reason why lexer and parser have to be entangled in Haskell
guess I'll have to use the symbolic character as a condition for layout_end and hope for the best
One more case is
then
BTWhow so?
You can do
if do True then ...
indeed, that confuses my parser as well
Or
does that apply to other layouts or only
do
?if a where a = 1 then
nope that's a parse error
right,
where
isn't allowed after just any expressionHmm,
let
is always guarded by something, andwhere
could only appear inside of it or in top level blockI'm beginning to think that I should track
do
separately from the other layoutsI mean, if you did the same trick for all of them, what would happen? It will end up with parse error anyway, won't it?
a = if case 5 of 5 -> True then 1 else 1
this is weird
But if you want to be GHC-complaint, you do have to support
NonDecreasingIndetation
, sodo
actually ends up being different after all:thinking:
TheMatten said:
why does that make it different?
You accept layout of
do
starting at the same level as the previous oneThis doesn't apply to other layouts AFAIK
ugh come on!
welp, guess it's time to rewrite the layout handler
do you have a link for
NonDecreasingIndentation
?or is that encoded in the layout section of the syntax reference?
https://downloads.haskell.org/ghc/latest/docs/html/users_guide/bugs.html?highlight=nondecreasingindentation#context-free-syntax
"bugs"
In principle it's matter of switching
>
for>=
in case ofdo
layout"but not in Haskell2010 mode"?
does that mean it's impossible to tell whether it's legal to use the same indent?
(just by parsing the file)
I guess that applies to all syntactic extensions
well it's simple to assume that a
\case
means we want LambdaCaseBut what about
static
keyword? :big_smile:right
or
proc do
or
rec
That's basically why I've decided to work with
Haskell2010
in Hask - there's just too much stuff in GHC :sweat_smile:well if you're lucky the parser will just decide the right variant of
rec
being keyword or identifierin my case, the parse tree isn't used for typing afterwards, so it doesn't matter