I am confused as to why this bit of F# code fails to compile:
open System
[<RequireQualifiedAccess>]
module Al =
[<return: Struct>]
let inline (|EquivalentName|_|) (name1: string) (name2: string) : unit voption =
ValueNone // irrelevant
[<return: Struct>]
let inline (|EquivalentNameSpans|_|) (name1: ReadOnlySpan<char>) (name2: ReadOnlySpan<char>) : unit voption =
ValueNone // irrelevant
let inline EquivalentNameSpans' (name1: ReadOnlySpan<char>, name2: ReadOnlySpan<char>) : unit voption =
ValueNone // irrelevant
let test() =
// Ok
match "foo" with
| Al.EquivalentName "foo" -> ()
| _ -> ()
// Ok
match "foo".AsSpan() with
| Al.EquivalentNameSpans "foo" -> () // Warning 3391 on second "foo" literal
| _ -> ()
// Ok
match "foo" : ReadOnlySpan<char> with
| Al.EquivalentNameSpans "foo" -> () // Warning 3391 on both "foo" literals
| _ -> ()
// Ok
match Al.EquivalentNameSpans'("foo", "foo") with
| ValueNone -> ()
| ValueSome _ -> ()
//error FS0001: Type mismatch. Expecting a
// 'string -> 'a voption'
//but given a
// 'ReadOnlySpan<char> -> unit voption'
//The type 'string' does not match the type 'ReadOnlySpan<char>'
//error FS0001: Type mismatch. Expecting a
// 'string -> 'a voption'
//but given a
// 'ReadOnlySpan<char> -> unit voption'
//The type 'string' does not match the type 'ReadOnlySpan<char>'
match "foo" with
| Al.EquivalentNameSpans "foo" -> () // error on this line
| _ -> ()
Generally, the F# compiler seems perfectly able to implicitly convert string
to ReadOnlySpan<char>
, albeit with a warning, but here, in the context of an active pattern, it fails to convert - what gives?
Open in sharplab.