From 25266b7cecc17adbfd6147ccb307582a8862a8f6 Mon Sep 17 00:00:00 2001 From: Dillon Kearns Date: Thu, 2 Apr 2026 16:57:14 -0700 Subject: [PATCH] Fix lambda not parenthesized on left side of operators. When a lambda appeared as the left operand of <| (pipeLeft), it was rendered without parentheses: \x -> x <| "hello" This is parsed as \x -> (x <| "hello"), not (\x -> x) <| "hello". The fix extends the existing right-side lambda parenthesization (from PR #132) to also handle the left side. Co-Authored-By: Claude Opus 4.6 (1M context) --- src/Internal/Write.elm | 14 ++++++++++---- tests/OperatorPrecedence.elm | 16 ++++++++++++++++ 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/src/Internal/Write.elm b/src/Internal/Write.elm index be2fbfc..089df6a 100644 --- a/src/Internal/Write.elm +++ b/src/Internal/Write.elm @@ -1060,12 +1060,18 @@ prettyOperatorApplication aliases indent symbol dir (Node _ exprl) (Node _ exprr Right -> ( prec + 1, prec ) + -- Lambda expressions need explicit parentheses on either side + -- of operators. On the right: `a |> \x -> b` is ambiguous. + -- On the left: `\x -> x <| "hello"` absorbs <| into the body. ( left, breakLeft ) = - prettyExpressionInner aliases { precedence = lprec } indent exprl + case exprl of + LambdaExpression _ -> + prettyExpressionInner aliases { precedence = lprec } indent exprl + |> Tuple.mapFirst Pretty.parens + + _ -> + prettyExpressionInner aliases { precedence = lprec } indent exprl - -- Lambda expressions on the right side of operators like |> - -- need explicit parentheses because `a |> \x -> b |> \y -> c` - -- is ambiguous — the second |> could be inside the lambda body. ( right, breakRight ) = case exprr of LambdaExpression _ -> diff --git a/tests/OperatorPrecedence.elm b/tests/OperatorPrecedence.elm index 986a310..74f56c0 100644 --- a/tests/OperatorPrecedence.elm +++ b/tests/OperatorPrecedence.elm @@ -133,4 +133,20 @@ pipes = (Elm.fn (Elm.Arg.var "y") (\y -> y)) |> Elm.Expect.renderedAs """"hello" |> (\\x -> x) |> (\\y -> y)""" + , test "pipeLeft with lambda is parenthesized" <| + \_ -> + Elm.Op.pipeLeft + (Elm.fn (Elm.Arg.var "x") (\x -> x)) + (Elm.string "hello") + |> Elm.Expect.renderedAs + """(\\x -> x) <| "hello\"""" + , test "pipeLeft with lambda applied to complex expression" <| + \_ -> + Elm.Op.pipeLeft + (Elm.fn (Elm.Arg.var "x") + (\x -> Elm.Op.append x (Elm.string "!")) + ) + (Elm.string "hello") + |> Elm.Expect.renderedAs + """(\\x -> x ++ "!") <| "hello\"""" ]