Fsharp: Error message "This function takes too many arguments..." can be improved

Created on 7 Jun 2018  路  2Comments  路  Source: dotnet/fsharp

When a function is used as an argument where a value type is expected, FS0002 is thrown. It seems to make more sense to use a type error in such case, as raising FS0002 is rather confusing.

image

Repro steps

Consider this, or any similar snippet where an argument of a non-function type is expected:

f# let x = Seq.init (fun x -> Result.Ok x)

Expected behavior

It should raise something similar to:

error FS0001: This expression was expected to have type 'int' but here has type ''a -> Result<'a>'

Or if FS0002 is _by design_, perhaps it can be improved if the compiler can detect the case where it is in fact a type error and give a more descriptive error detailing what would otherwise be shown with FS0001.

Actual behavior

Instead it raises:

error FS0002: This function takes too many arguments, or is used in a context where a function is not expected

This is confusing as it is besides the point (even though the last part says "used in a context where a function is not expected", this is hard to grok, even more so since many programmers are puzzled by the concept of 'context').

Known workarounds

N/A

Related information

Any current F# version, including latest.

As an aside, type inference in the screenshot shows that x is of type ((int -> obj) -> seq<obj>), I have no clue why it thinks that, it is clearly confused...

Area-Compiler Severity-Low bug

All 2 comments

@abelbraaksma I agree the message is confusing and your proposed expected behaviour would make sense AFAICS.

Tracking down the error message, it stems from throwing FunctionExpected in UnifyFunctionType https://github.com/Microsoft/visualfsharp/blob/ad77930e44276dd28a34372145f61be8197150a9/src/fsharp/TypeChecker.fs#L736-L742

while the other (FS0001) is in OutputPhasedErrorR https://github.com/Microsoft/visualfsharp/blob/ad77930e44276dd28a34372145f61be8197150a9/src/fsharp/CompileOps.fs#L695-L701 where there seems to be couple of special cases (tuples and bool ref apparently).

The challenge on this one is to find the higher level place in the stacktrace where the branch occurs on the expression type, it doesn't seem as easy as some other error message adjustments I've encountered so far.

If you want to give it a look, you can debug FSI and use your sample code, having break point in UnifyFunctionType and walking back the stack would be the first step to investigate further.

Maybe someone more familiar with that kind of error adjustment can complement those first elements.

Going to label this as a bug rather than an improvement, as this does not look like the correct error message to emit.

Was this page helpful?
0 / 5 - 0 ratings