dotnet / dotnet/fsharp

Incorrect error message with applicative Computation Expressions

Open
#12,607 0 comments 0 reactions 0 assignees View on GitHub
Area-Diagnostics Bug Impact-Low
Dominant language
F#
Stars
4.3k
Forks
876
Avg merge
4d 11h
Merged PRs (30d)
131

Description

When creating an Applicative Computation Expression (`CE`) if you forgot to include the function parameter at the end of a `BindN` method, the error message.

Here's a code snippet I have using VSCode with the Ionide extension.

___

NOTE: This computation expression is wrong, if you came to this github issue trying to figure out how a `BindN` method should be structured and executed, ignore the following snippet and look below).

___

```
type OptionBuilder() =
member _.Bind(option, binder) = Option.bind binder option
member _.Return(value) = Some value
member _.Bind3(o1, o2, o3) = // Wrong signature
match o1, o2, o3 with
| Some v1, Some v2, Some v3 -> Some(v1, v2, v3) // Wrong return
| _ -> None

let option = OptionBuilder()

option {
let! a = Some 1
and! b = Some 2
and! c = Some 3

return a + b + c // This will never get hit by the CE above
}
```

If possible attach a zip file with the repro case. This often makes it easier for others to reproduce.
The zip file should ideally represent the situation just before the call/step that is problematic.

**Expected behavior**

An error message on `let! a = ...` that reads:

`The member or object constructor 'Bind3' takes 4 argument(s) but is here given 3. The required signature is 'member OptionBuilder.Bind3: o1: 'a0 option * o2: 'a1 option * o3: 'a2 option * ('a0 * 'a1 * 'a2 -> 'a3 option) -> 'a3 option'`

**Actual behavior**

An error message on `let! a = ...` that reads:

`The member or object constructor 'Bind3' takes 3 argument(s) but is here given 4. The required signature is 'member OptionBuilder.Bind3: o1: 'a0 option * o2: 'a1 option * o3: 'a2 option -> ('a0 * 'a1 * 'a2) option'.`

**Known workarounds**

N/A

**Related information**

VS Code, Ionide Extension

Correct Version of the Computation Expression:

```
type OptionBuilder() =
member _.Bind(option, binder) = Option.bind binder option
member _.Return(value) = Some value
member _.Bind3(o1, o2, o3, f) =
match o1, o2, o3 with
| Some v1, Some v2, Some v3 -> f (v1, v2, v3)
| _ -> None

let option = OptionBuilder()

option {
let! a = Some 1
and! b = Some 2
and! c = Some 3

return a + b + c
} // Some 6

option {
let! a = Some 1
and! b = Some 2
and! c = None

return a + b + c
} // None
```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.