ormolu icon indicating copy to clipboard operation
ormolu copied to clipboard

Treat function application with final list same as final do-block

Open brandon-leapyear opened this issue 3 years ago • 9 comments

Is your feature request related to a problem? Please describe. In my mind, a final do-block and a long final list should be formatted the same, something like

a1 = x "asdf" $ do
  asdf <- foo
  return asdf

a2 = x "asdf"
  [ foo
  , foo2
  ]

But ormolu currently formats the second one differently from the first (which is already formatted correctly):

a = x "asdf" $ do
  asdf <- foo
  return asdf

a2 =
  x
    "asdf"
    [ foo,
      foo2
    ]

This shows up a lot in tasty tests, where i'd like the format

myTests = testGroup "group1"
  [ testCase "foo" $ do
      foo 1 @?= ...
  ]

but the testGroup format becomes different from the testCase format after ormolu:

myTests =
  testGroup
    "group1"
    [ testCase "foo" $ do
        foo 1 @?= ...
    ]

Describe the solution you'd like Treat a long final argument the same as a do-block.

Describe alternatives you've considered

Additional context

brandon-leapyear avatar Mar 13 '21 19:03 brandon-leapyear

You might have already considered it, but you can at least avoid the line break between the function arguments using a $ there:

a2 =
  x "asdf" $
    [ foo,
      foo2
    ]

mheinzel avatar Mar 13 '21 21:03 mheinzel

hm but wouldnt that violate hlint's redundant $ rule?

brandonchinn178 avatar Mar 13 '21 23:03 brandonchinn178

Yes, depending on your hlint configuration (I personally usually disable it).

mheinzel avatar Mar 14 '21 13:03 mheinzel

Copied over from https://github.com/fourmolu/fourmolu/issues/46:

Essentially, where an expression is only multiline because it ends with a particular multiline-friendly construct (this is a bit vague, but definitely includes record update and construction. case and \case statements, multi-way-if, and probably list literals), I'd like to format the preceding part of the expression in single-line style. As an extreme case, we currently turn:

f = g 1 2 3 4 5 R
    { a = ()
    , b = ()
    }

in to:

f =
    g
        1
        2
        3
        4
        5
        R
            { a = ()
            , b = ()
            }

while the above example is exacerbated by configuring Fourmolu to use 4-space indentation, it's still an issue in plain Ormolu:

f =
  g
    1
    2
    3
    4
    5
    R
      { a = (),
        b = ()
      }

when I think it would be better if Ormolu could do

f =
  g 1 2 3 4 5 R
    { a = (),
      b = ()
    }

or even

f =
  g 1 2 3 4 5
    R
      { a = (),
        b = ()
      }

(which you could get with a $ before R, as mentioned by @mheinzel above, but hlint complains about unnecessary $)

brandonchinn178 avatar Apr 18 '22 18:04 brandonchinn178

Note: @mheinzel's workaround no longer works with the new infix behavior:

a2 =
  x "asdf"
    $ [ foo,
        foo2
      ]

It also gets exacerbated with a long chain of function compositions. Compare:

myTests =
  testGroup "group" . concat $ do
    [ tests1,
      tests2
      ]

myTests =
  testGroup "group"
    . concat
    $ [ tests1,
        tests2
      ]

brandonchinn178 avatar May 20 '23 21:05 brandonchinn178

@brandonchinn178 Maybe you are misled by the behavior in Ormolu Live? If you format your examples locally with the CLI, or alternatively, in the Ormolu Live from https://github.com/tweag/ormolu/pull/1029#issuecomment-1555949752), it should still work fine, as before.

amesgen avatar May 20 '23 21:05 amesgen

Ah I see. It's a variant of this new issue, then: https://github.com/tweag/ormolu/issues/1032

brandonchinn178 avatar May 20 '23 21:05 brandonchinn178

@mrkkrp Any comments on this? If a PR were submitted for this, would it be accepted?

Fourmolu might start moving on this if Ormolu isn't interested, but it'd be really great to avoid the divergence if possible

brandonchinn178 avatar Oct 02 '23 23:10 brandonchinn178

@brandonchinn178 I don't really see a good reason to introduce an exception for how a multiline function application is formatted in this case. I'd value consistency more even when a list is involved.

mrkkrp avatar Oct 03 '23 07:10 mrkkrp