【问题标题】:Pipeline operator refuses to work管道操作员拒绝工作
【发布时间】:2013-12-25 10:59:57
【问题描述】:

我不明白为什么会这样

let data = 
    JsonConvert.DeserializeObject<Dictionary<string, Dictionary<string, string>>>(
         File.ReadAllText <| Path.Combine(myPath, "ejv.json"))

没关系,虽然这个

let data = 
    JsonConvert.DeserializeObject<Dictionary<string, Dictionary<string, string>>> 
    <| File.ReadAllText
    <| Path.Combine(myPath, "ejv.json")

给我两个错误,第一个是:

第二个是:

我做错了什么?

更新 @Patryk Ćwiek 提出了一个很好的编辑建议,这似乎可以修复类型错误:

let data = JsonConvert.DeserializeObject<Dictionary<string, Dictionary<string, string>>> 
       << File.ReadAllText 
       <| Path.Combine(myPath, "ejv.json")

但它产生了另一个令人费解的消息:意外的类型参数。 截图如下:

我可以轻松摆脱它删除&lt;Dictionary&lt;string, Dictionary&lt;string, string&gt;&gt;&gt;,但在这种情况下,我的数据是object 类型,而不是Dictionary。我可以以某种方式保存类型信息并使用流水线吗?

解决方案

感谢@Patryk Ćwiek 解决方案如下:

let d<'a>(s:string) = JsonConvert.DeserializeObject<'a>(s)
let data = 
    Path.Combine(myPath, "ejv.json") 
    |> File.ReadAllText 
    |> d<Dictionary<string, Dictionary<string, string>>> with 

我不知道为什么,但是没有那个别名 d 它就不起作用。

【问题讨论】:

    标签: generics f# pipeline


    【解决方案1】:

    据我所知,评估是从左到右进行的,所以你的第二个表达式相当于:

    let data = 
        (JsonConvert.DeserializeObject<Dictionary<string, Dictionary<string, string>>> <| File.ReadAllText)
        <| Path.Combine(myPath, "ejv.json")
    

    注意操作流程。这意味着您首先将一个函数传递给DeserializeObject,这可能不是您想要做的。

    当你这样做时:

    let data = 
        JsonConvert.DeserializeObject<Dictionary<string, Dictionary<string, string>>> 
        <| (File.ReadAllText <| Path.Combine(myPath, "ejv.json"))
    

    它会起作用的。这相当于您的第一个选项。

    其他解决方案是反转管道以使数据流更自然:

    let data = Path.Combine(myPath, "ejv.json") 
               |> File.ReadAllText 
               |> JsonConvert.DeserializeObject<Dictionary<string, Dictionary<string, string>>>
    

    编辑

    我忽略了一个不太常用的选项。您也可以使用函数组合运算符&lt;&lt; 使其工作:

    let data = JsonConvert.DeserializeObject<Dictionary<string, Dictionary<string, string>>> 
               << File.ReadAllText 
               <| Path.Combine(myPath, "ejv.json")
    

    它本质上将DeserializeObject : string -&gt; 'aReadAllText : string -&gt; string 组合成(在上面的示例中未命名)函数f : string -&gt; 'a,其中f(s) = DeserializeObject(ReadAllText(s))。然后它通过管道将Path.Combine 的结果输入f

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-08-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-16
    • 2012-06-25
    • 1970-01-01
    • 2022-11-10
    相关资源
    最近更新 更多