Tip 1: Reference the System.XML assembly from FSI so you play with the REPL. To do this I add the #r in block comments at the top of the file like so:
(* Press Alt-' to send the below to the interpreter. #r @"C:\Windows\Microsoft.NET\Framework\v4.0.30319\System.Xml.Linq.dll" *) open System.Xml.LinqTip 2: F# doesn’t perform implicit conversions. Lets assume you’re translating the following C# code:
var xelements = XElement.Parse("<myXML/>"); var interestingElements = xelements.Descendants("myXML");The naive translation below doesn’t work because XElement.Decendants doesn’t take a string, it takes an XName.
//FAILS to compile This expression was expected to have type XName but here has type string let interestingElements = xelements.Descendants "myXML"The reason the above code works in C# is because an implicit conversion operator exists and is called. However in F# implicit conversions are not called, and you have to call them yourself, something like the painful to read:
let interestingElements = xelements.Descendants <| XName.op_Implicit "myXML";Now, it turns out we can use duck typing to make an implicit conversion operator (this is mentioned lots of places on the web but I’ll repeat it for succinctness)
// Create an implicit conversion operator, it's inline which means it will work on any types that support the implicit conversion. // This is duck typing. let inline convert_implicit(arg : ^source) : ^target = ((^source or ^target) : (static member op_Implicit : ^source -> ^target) (arg))And finally we can write the code I needed:
let interestingElements = xelements.Descendants <| convert_implicit "myXML";