juvix
juvix copied to clipboard
Properly newline expressions in the pretty printer
I was looking at Juvix examples today, and many examples are quite hard to read
--- Given a player attempted move, updates the state accordingly.
playMove : Maybe Nat → GameState → GameState;
playMove nothing (state b p _) := state b p (continue "\nInvalid number, try again\n");
playMove (just k) (state (board s) player e) := if (not (elem (==) k (possibleMoves (flatten s)))) (state (board s) player (continue "\nThe square is already occupied, try again\n")) (checkState (state (board (map (map (replace player k)) s)) (switch player) noError));
Namely the text goes off the screen since it is over 270
characters long. Would be good to have a mechanism that can newline at 80
or 90
characters long automatically in the pretty printed. Should be easy to implement and would improve readability quite a bit.
It seems the changes make it harder to read, let me explain
playMove : Maybe Nat → GameState → GameState;
playMove nothing (state b p _) := state b p (continue
"\nInvalid number, try again\n");
playMove (just k) (state (board s) player e) := if (not (elem (==) k
(possibleMoves (flatten s)))) (state (board s) player (continue
"\nThe square is already occupied, try again\n")) (checkState (state (board
(map (map (replace player k)) s)) (switch player) noError));
the (
after the if is more forward than the line after it, making watching a sense of nesting hard. This gets worse in player (continue
as the same indentation level stays the same, meaning it's impossible to see where expressions end. is (checkState ...)
apart of continue? I can't tell!
A plan
I think there still is an easy way to fix this, the library seems heavily inspired from what I currently use in projects
Make an block (group in the library terms), where you align each argument of a function together, that way they either all newline or don't. Probably best to indent things like
if (won (state b p e))
(state b p (terminate ("Player " ++str (showSymbol (switch p)) ++str " wins!")))
(if (draw (state b p e))
(state b p (terminate "It's a draw!"))
(state b p e));
Where the align
ment starts after the function word (if
in this case).
Thankfully It seems the library has done most of the work already with encloseSep, and you can likely just invoke it as follows
"app" <+> align (encloseSep lparen rparen space (map pretty [1,20,300,4000]))
Infix functions will take more effort as you'll want to decide on infix on the next line or end of the line, which affects how you ought to format.
#1581 closes this