F # passing none to a function, getting null as a parameter value

This is really weird, and I'm afraid I just did something dumb, but I can't figure it out.

I pass the Nonefunction someas the first parameter, but when the function is executed, the value parentNodeis null (I do not deal with what it prints null for None, the value of the parameter of the IS function is not null None). I get a null error in the line of the print function because parentNode is null. I tried to encode the arguments and reorder, but that didn't help. I have a suspicious suspicion that this has something to do with curry, but I'm at a loss ...

I had to replace the true url value with an empty string for company problems, but this is the xsd url if that helps

Here is the code:

#light
open System
open System.Xml
open System.Net
open System.Collections.Generic

type StartResult =
    | Parameters of XsdParserParameters
    | Xsd of Xsd

and Xsd(text) =
    let rows = new List<string>()

    member this.Text
        with get() = text

    member this.Rows
        with get() = rows

and XsdParserParameters() =
    let mutable url = ""

    member this.Url
        with get() = url
        and set(value) = url <- value

    member this.Start() =
        try
            use client = new WebClient()
            let xsd = client.DownloadString(this.Url)
            StartResult.Xsd(Xsd(xsd))
        with e ->
            StartResult.Parameters(this)

let processor () =
    let parameters = XsdParserParameters()
    parameters.Url <- ""
    match parameters.Start() with
    | StartResult.Parameters(xpparams) ->
        //some error
        ()
    | StartResult.Xsd(xsd) ->

        let rec some (parentNode : XmlNode option) (node : XmlNode) =
            let a = ()

            for subNode in node.ChildNodes do
                match subNode.LocalName with
                | "complexType" ->
                    xsd.Rows.Add(
                        sprintf
                            "%O~%s~%d~%d~%s~%s~%O" 
                            parentNode 
                            subNode.Value 
                            1 
                            1 
                            (subNode.Attributes.GetNamedItem("name").Value)
                            "" 
                            false)
                    some (Some(subNode)) subNode 
                | "sequence" ->
                    some parentNode subNode 
                | "element" ->
                    xsd.Rows.Add(
                        sprintf 
                            "%O~%s~%d~%d~%s~%s~%O" 
                            parentNode 
                            subNode.Value 
                            1 
                            1 
                            (subNode.Attributes.GetNamedItem("name").Value) 
                            "" 
                            false)
                    some (Some(subNode)) subNode 
                | _ ->
                    ()

        let xdoc = new XmlDocument();
        xdoc.LoadXml(xsd.Text)

        some (None) (xdoc.DocumentElement)

processor()

printfn "Done..."
Console.ReadLine() |> ignore
+5
source share
2 answers

Unfortunately, this is the way F # outputs None:

> sprintf "%O" None;;
val it : string = "<null>"

You can easily write a custom function sprintffor a type option, for example:

let sprintOption v = 
    if Option.isNone v then "None" else sprintf "%A" v
+4
source

Option<'T>(the source on Github ) uses the attribute [<CompilationRepresentation([CompilationRepresentationFlags.UseNullAsTrueValue)>], which causes the null register ( Nonein this case) to be represented nullat run time.

+4
source

All Articles