fantomas
fantomas copied to clipboard
Broken comma in match expression in parameter invocation
Issue created from fantomas-online
Code
module Utils
type U = A of int | B of string
type C() =
member this.M (a : int, b : string) = ()
let f () =
let u = A 0
do C().M(
match u with
| A i -> i
| B _ -> 0
,
match u with
| A _ -> ""
| B s -> s
)
Result
module Utils
type U =
| A of int
| B of string
type C() =
member this.M(a: int, b: string) = ()
let f () =
let u = A 0
do
C()
.M(
match u with
| A i -> i
| B _ -> 0,
match u with
| A _ -> ""
| B s -> s
)
Problem description
When using a match expression as a parameter argument, the comma that separates parameters can be misinterpreted by the F# compiler as a tuple separator.
Options for disambiguating include:
- Wrapping the match expression in parenthesis
- Adding a newline after the match expression (as shown in the pre-format code)
Extra information
- [x] The formatted result breaks by code.
- [ ] The formatted result gives compiler warnings.
- [x] I or my company would be willing to help fix this.
Options
Fantomas Master at 08/11/2021 17:06:14 - 383b729f46ebc01dde282967c68337d5ad55fa17
Default Fantomas configuration
Did you know that you can ignore files when formatting from fantomas-tool or the FAKE targets by using a .fantomasignore file?
This is quite the horrible code you have there. I would advise against passing match expressions as arguments. That being said I would accept a PR that extends the check we have in
https://github.com/fsprojects/fantomas/blob/a80f888cbb71e8d0bd65d05c6ceccf9502d30f69/src/Fantomas/CodePrinter.fs#L916-L950
so that in this case, the comma is also flipped.
I think I also hit this issue but with function matching.
Old Code
module Util
open Aether
let inline non<'a when 'a : equality> (def : 'a) : Lens<'a option, 'a> =
( function
| Some(a) -> a
| None -> def
, fun a _ -> if a = def then None else Some(a)
)
Note that Aether's lens is a tuple of getter and setter so are defining a tuple of functions.
Result of formatting
let inline non<'a when 'a: equality> (def: 'a) : Lens<'a option, 'a> =
(function
| Some (a) -> a
| None -> def, (fun a _ -> if a = def then None else Some(a)))
With the formatting, the F# compiler complains error FS0002: This function takes too many arguments, or is used in a context where a function is not expected
I worked around it by putting parens around the getter function, so fantomas formats it to
let inline non<'a when 'a: equality> (def: 'a) : Lens<'a option, 'a> =
((function
| Some (a) -> a
| None -> def),
(fun a _ -> if a = def then None else Some(a)))
Which compiles but is still somewhat confusing to read since you don't instantly notice the comma
I believe this issue is fixed. A regression test could close this issue.