Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

F# and explicit conversion in LINQ to XML

In C# I can express this:

var xe = XElement.Parse("<foo></foo>");
var maybe = (bool?)xe.Element("bar");

How can this be expressed in F#?

Edit: I did find this helper function

let inline conv (x : ^a) : ^b = ((^a or ^b) : (static member op_Explicit : ^a -> ^b) (x))
like image 936
Bent Rasmussen Avatar asked Nov 13 '13 22:11

Bent Rasmussen


1 Answers

Unfortunately, XLinq relies heavily on implicit and explicit conversions, which makes things a bit difficult.

You can make a routine to convert from an XElement to a bool option:

let elementToBool e =
  match e with
    | null -> None
    | e -> Some(XElement.op_Explicit e : bool)

With this, you can write:

let xe = XElement.Parse("<foo><baz>true</baz></foo>")
let bar = xe.Element (XName.op_Implicit "bar") |> elementToBool
let baz = xe.Element (XName.op_Implicit "baz") |> elementToBool

In F# Interactive, this will convert to:

val bar : bool option = None 
val baz : bool option = Some true

Note that you can use the helper function you found, though you'd also need one for the op_Implicit calls as well.

Using the converter functions this becomes a bit cleaner. I've adapted the code above to use (slightly modified versions of) your converter helper routine:

let inline convi (x : ^a) : ^b = ((^a or ^b) : (static member op_Implicit : ^a -> ^b) x)
let inline conve (x : ^a) : ^b = ((^a or ^b) : (static member op_Explicit : ^a -> ^b) x)

let xe = XElement.Parse("<foo><baz>true</baz></foo>")
let elementToBool e =
  match e with
    | null -> None
    | e -> Some(conve e : bool)

let baz = "baz" |> convi |> xe.Element |> elementToBool
let bar = "bar" |> convi |> xe.Element |> elementToBool
like image 113
Reed Copsey Avatar answered Oct 13 '22 09:10

Reed Copsey