[style-guide] Multiline type annotations
The current guidance doesn't explicitly state the best practice regarding multiline type annotations.
Abstractly put:
p: t
Where t is multiline or crossed the maximum line length.
I propose to simply indent t on the following line if these conditions are met.
p:
t
Some examples to illustrate:
type ExprFolder<'State> =
{ exprIntercept:
('State -> Expr -> 'State) -> ('State -> Expr -> 'State -> 'State -> Exp -> 'State }
let UpdateUI
(theModel:
#if NETCOREAPP2_1
ITreeModel
#else
TreeModel
#endif
)
(info: FileInfo) =
// code
()
let f
(x:
{|
x: int
y: AReallyLongTypeThatIsMuchLongerThan40Characters
|})
=
x
I believe in practice, this won't show up that much. Nevertheless, the principle still holds and is consistent with other parts of the guide. It also does not introduce any vanity alignments.
Some further context can be found in https://github.com/fsprojects/fantomas/pull/2424#issuecomment-1230033101
Somewhat related, if t is placed on the next line, depending on what it is, it might still need alternate formatting to respect the max_line_length.
If t is a long tuple type, I would also split it onto multiline lines. Similar to how signature files are described in the guide.
p:
a *
b *
c
Relevant example:
type Meh
(
input:
LongTupleItemTypeOneThing *
LongTupleItemTypeThingTwo *
LongTupleItemTypeThree *
LongThingFour *
LongThingFiveYow
) =
class
end
For lambda expression, in the bizarre case that the arguments cannot fit on the same line of the fun keyword, I would indent them on the next line.
fun
(a: t1)
(b: t2) ->
()
Relevant example:
let useAddEntry () =
fun
(input:
{| name: string
amount: Amount
isIncome: bool
created: string |}) ->
// foo
bar ()
//cc @dsyme @josh-degraw