In some situations the compiler tries to unify a type argument contained in a generic type with the generic type itself.
Repro steps
open System
open System.Collections.Generic
let pInt = Int32.TryParse >> function (true, x) -> Some x | _ -> None
let pString (x:string) =
match x.Trim() with
| x when x.[0..0] = "\"" && x.[x.Length-1..x.Length-1] = "\"" -> Some x.[1..x.Length-2]
| _ -> None
let pTuple2 p1 p2 (x:string) =
match x.Trim() with
| x when x.[0..0] = "(" && x.[x.Length-1..x.Length-1] = ")" ->
let x = x.[1..x.Length-2]
match x.Split(',') with
| [|a; b|] -> match (p1 a, p2 b) with (Some a, Some b) -> Some (a, b) | _ -> None
| _ -> None
| _ -> None
let pList (p:string -> 'a option) (x:string) =
match x.Trim() with
| x when x.[0..0] = "[" && x.[x.Length-1..x.Length-1] = "]" ->
let x = x.[1..x.Length-2]
let x = x.Split(';') |> Array.map p
if x |> Array.forall (fun x -> x.IsSome) then
Some (Array.choose id x |> Array.toList)
else None
| _ -> None
type TryParseCs = TryParseCs with
static member TryParse (_: int ) = pInt
static member TryParse (_: string) = pString
let inline iTryParse (a: ^a, b: ^b) = ((^a or ^b) : (static member TryParse: ^b -> (string -> ^b option)) b)
let inline tryParse (x: string) : 'a option = iTryParse (TryParseCs, Unchecked.defaultof<'a>) x
type TryParseCs with
static member inline TryParse (_: IDictionary<string, 'a>) : string -> option<IDictionary<string, 'a>> =
pList (pTuple2 pString tryParse) >> function
| Some x -> Some (dict x )
| _ -> None
static member inline TryParse (_: 'a ResizeArray) : string -> option<'a ResizeArray> = pList tryParse >> function
| Some x -> Some (ResizeArray<_>(x))
| _ -> None
Expected behavior
val inline tryParse :
x:string -> ^a option
when (TryParseCs or ^a) : (static member TryParse : ^a ->
string ->
^a option)
Actual behavior
It doesn't compile
~vs4AFB.fsx(43,98): error FS0043: Type mismatch. Expecting a
string -> 'a option
but given a
string -> ResizeArray<'a> option
The resulting type would be infinite when unifying ''a' and 'ResizeArray<'a>'
Known workarounds
At the end of the code add this overload:
static member TryParse (_: 'a Tuple) : string -> option<Tuple<'a>> = fun _ -> Some (Tuple<'a>(Unchecked.defaultof<'a>))
Related information
This was reported as a bug in Fleece.
In some situations the compiler tries to unify a type argument contained in a generic type with the generic type itself.
Repro steps
Expected behavior
Actual behavior
It doesn't compile
Known workarounds
At the end of the code add this overload:
Related information
This was reported as a bug in Fleece.