F#传球没有发挥作用,让null作为参数值发挥作用、参数、null

2023-09-04 00:21:48 作者:女施主请放心,贫僧只劫色

这是很奇怪的,我怕我刚做了愚蠢的事情,但我不明白。

我通过的功能部分作为第一个参数,但该函数执行时,值对 parentNode 为空(我不关心它打印为null ,功能参数值为NULL不)。我结束了在打印功能线得到一个空引用错误,因为parentNode为空。我试着元组的指定参数和更改订单,但没有帮助。我有一个鬼鬼祟祟的怀疑,这已经是与柯里但我不知所措......

我不得不与公司问题的一个空字符串代替真实的URL值,但它是一个网址为XSD是否有帮助

下面是code:

  #light
开放系统
开放的System.Xml
开System.Net
开System.Collections.Generic

键入StartResult =
    | XsdParserParameters参数
    | XSD的XSD

和XSD(文字)=
    让行=新的名单,其中,串>()

    会员this.Text
        以get()=文本

    会员this.Rows
        以get()=行

和XsdParserParameters()=
    让可变URL =

    会员this.Url
        以get()=网址
        并设置(值)= URL<  - 值

    会员this.Start()=
        尝试
            使用客户端=新的Web客户端()
            让XSD = client.DownloadString(this.Url)
            StartResult.Xsd(XSD(XSD))
        随e  - >
            StartResult.Parameters(本)

让处理器()=
    让参数= XsdParserParameters()
    parameters.Url<  - 
    匹配parameters.Start()与
    | StartResult.Parameters(xpparams) - >
        //一些错误
        ()
    | StartResult.Xsd(XSD) - >

        让拍摄一些(parentNode:XmlNode的选项)(节点:XmlNode的)=
            让=()

            对于子节点的node.ChildNodes做
                比赛subNode.LocalName与
                | 复杂类型 - >
                    xsd.Rows.Add(
                        的sprintf
                            %O〜%S〜%D〜%D〜%S〜%S〜%O
                            parentNode
                            subNode.Value
                            1
                            1
                            (subNode.Attributes.GetNamedItem(名)。值)
                            
                            假)
                    一些(部分(子节点))子节点
                | 序 - >
                    一些parentNode子节点
                | 元素 - >
                    xsd.Rows.Add(
                        的sprintf
                            %O〜%S〜%D〜%D〜%S〜%S〜%O
                            parentNode
                            subNode.Value
                            1
                            1
                            (subNode.Attributes.GetNamedItem(名)。值)
                            
                            假)
                    一些(部分(子节点))子节点
                | _  - >
                    ()

        XDOC就让=新的XmlDocument();
        xdoc.LoadXml(xsd.Text)

        一些(无)(xdoc.DocumentElement)

处理器()

printfn完成......
到Console.ReadLine()|>忽略
 
获奖名单出炉 快来看看有没有你

解决方案

不幸的是,它的方法F#打印出

 > sprintf的%O无;;
VAL是:字符串=<零>中
 

您可以轻松地编写自定义的sprintf 功能选项键入,例如:

 让sprintOption V =
    如果Option.isNone V,那么无别人的sprintf%AV
 

This is really weird and I fear I have just done something dumb but I can't figure it out.

I'm passing None to the function some as the first parameter but when the function executes, the value of parentNode is null (I'm not concerned with it printing null for None, the function parameter value IS null not None). I end up getting a null reference error on the print function line because parentNode is null. I've tried to tuple the args and change the order but that didn't help. I have a sneaking suspicion that this has something to do with currying but I'm at a loss...

I had to replace the real url value with an empty string for company issues but it is a url to an xsd 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

解决方案

Unfortunately, it's the way F# prints out None:

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

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

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