I have been experimenting with type providers but am unable to parse input to a union type of two type provider types.
type Vegetable = JsonProvider<"path">
type Fruit = XmlProvider<"path">
type Thingy = V of Vegetable.Root | F of Fruit.Fruit
type EncapsulatingRec = {name:string ; item:Thingy}
let listOfEncRec =
...
|> Array.map (fun path -> {
name = Path.GetDirectoryName path
item = File.ReadAllText path |> Vegetable.Parse
})
...
JetBrains Rider gives an error "This expression was expected to have type âThingyâ but here has type âJsonProvider<âŚ>.Rootâ
What is the issue? I have tried defining Thingy as
type Thingy = Vegetable | Fruit
The code works only when Thingy type is defined as
The issue I think comes down to the difference between âtaggedâ (or discriminated) unions vs âuntaggedâ unions (like you might see in typescript or python). In F#, all unions are âtagged.â That means that you have to use the âconstructorsâ of a union (here, thatâs V and F) in order to have an instance of the union. The union you have there is literally the union of V (with a Vegetable.Root attached to it) and F (with a Fruit.Fruit attached to it). Itâs not the union of Vegetable.Root and Fruit.Fruit
Are you familiar with the Option type at all? Option is just a discriminated union, and has the same issue:
To make my code snippet above compile, youâd have to change it to
To make your code compile, you have to do item = File.ReadAllText path |> Vegetable.Parse |> V