【问题标题】:F# - Can I return a discriminated union from a functionF# - 我可以从函数返回一个有区别的联合吗
【发布时间】:2015-06-30 08:07:20
【问题描述】:

我有以下几种:

type GoodResource = {
    Id:int;
    Field1:string }


type ErrorResource = {
    StatusCode:int;
    Description:string }

我有以下歧视性工会:

type ProcessingResult = 
    | Good of GoodResource
    | Error of ErrorResource

然后想要有一个函数,该函数将具有可区分联合处理结果的返回类型:

let SampleProcessingFunction value =
    match value with
    | "GoodScenario" -> { Id = 123; Field1 = "field1data" }
    | _ -> { StatusCode = 456; Description = "desc" }

这是我想要做的可能。编译器声明它期望 GoodResource 是返回类型。我错过了什么或者我完全以错误的方式解决了这个问题?

【问题讨论】:

    标签: f# functional-programming discriminated-union


    【解决方案1】:

    { Id = 123; Field1 = "field1data" }GoodResource 类型的值,而不是 ProcessingResult 类型的值。要创建ProcessingResult 类型的值,您需要使用它的两个构造函数之一:GoodError

    所以你的函数可以这样写:

    let SampleProcessingFunction value =
        match value with
        | "GoodScenario" -> Good { Id = 123; Field1 = "field1data" }
        | _ -> Error { StatusCode = 456; Description = "desc" }
    

    【讨论】:

      【解决方案2】:

      就目前而言,SampleProcessingFunction 为每个分支返回两个不同的类型。

      要返回 same 类型,您需要创建一个 DU(您已经这样做了),但还需要明确指定 DU 的大小写,如下所示:

      let SampleProcessingFunction value =
          match value with
          | "GoodScenario" -> Good { Id = 123; Field1 = "field1data" }
          | _ -> Error { StatusCode = 456; Description = "desc" }
      

      您可能会问“为什么编译器不能自动找出正确的大小写”,但是如果您的 DU 有两个 same 类型的案例会发生什么?例如:

      type GoodOrError = 
          | Good of string
          | Error of string
      

      在下面的示例中,编译器无法确定您指的是哪种情况:

      let ReturnGoodOrError value =
          match value with
          | "GoodScenario" -> "Goodness"
          | _ -> "Badness"
      

      所以你需要再次为你想要的情况使用构造函数:

      let ReturnGoodOrError value =
          match value with
          | "GoodScenario" -> Good "Goodness"
          | _ -> Error "Badness"
      

      【讨论】:

        【解决方案3】:

        您必须在任一分支中说明要返回的联合类型的大小写。

        let SampleProcessingFunction value =
            match value with
            | "GoodScenario" -> { Id = 123; Field1 = "field1data" } |> Good
            | _ -> { StatusCode = 456; Description = "desc" } |> Error
        

        我建议阅读 Scott Wlaschin Railway Oriented Programming 的这篇优秀文章

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-11-24
          • 2021-10-18
          • 1970-01-01
          • 2021-07-10
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多