FYI F # 4 added Option.ofObj
In F # null avoided for good reason. When we are dealing with C # libraries that rely on null , my general advice would be to provide the idiomatic F # βadapterβ in this library.
In practice, this can be quite a bit of work, and the result may not be as brief as the C # ?. Operator ?. (leaving aside the argument whether such an operator is a good idea or not).
As far as I know, the F # compiler does not support such an operator, but if you really feel it, you need to raise it: http://fslang.uservoice.com/ . The F # community is friendly, but I suspect you will have to argue quite a bit to convince the community that this is a good idea for F #.
In the same time; one way to make it a bit more concise is to create a calculation expression like this ( getAttributeValue will look like your code):
// Basically like the classic `maybe` monad // but with added support for nullable types module Opt = let inline Return v : Option<'T> = Some v let inline ReturnFrom t : Option<'T> = t let inline ReturnFrom_Nullable ot : Option<'T> = match ot with | null -> None | _ -> Some ot let inline Bind (ot : Option<'T>) (fu : 'T -> Option<'U>) : Option<'U> = match ot with | None -> None | Some vt -> let ou = fu vt ou let inline Bind_Nullable (vt : 'T) (fu : 'T -> Option<'U>) : Option<'U> = match vt with | null -> None | _ -> let ou = fu vt ou let Delay ft : Option<'T> = ft () type OptBuilder() = member inline x.Return v = Return v member inline x.ReturnFrom v = ReturnFrom v member inline x.ReturnFrom v = ReturnFrom_Nullable v member inline x.Bind (t, fu) = Bind t fu member inline x.Bind (t, fu) = Bind_Nullable t fu member inline x.Delay ft = Delay ft let inline ofObj o = match o with | null -> None | _ -> Some o open HtmlAgilityPack let opt = Opt.OptBuilder() let getAttributeValue (node : HtmlNode) (path : string) : string option = opt { let! nodes = node.SelectNodes path let! node = nodes.[0] let! attr = node.Attributes.["value"] return! attr.Value } let html = """ <html> <title>Hello</title> <body>Yellow <div name='Test' value='Stone'>Div</div></title> </html> """ [<EntryPoint>] let main argv = let doc = HtmlDocument () doc.LoadHtml html let r = getAttributeValue doc.DocumentNode "//div[@name='Test']" printfn "Result: %A" r 0
source share