F# - 我可以 return 一个函数的有区别的联合吗

F# - Can I return a discriminated union from a function

我有以下类型:

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


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

我有以下歧视联盟:

type ProcessingResult = 
    | Good of GoodResource
    | Error of ErrorResource

然后想要一个具有 return 类型的可区分联合 ProcessingResult 的函数:

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

我正在努力做到的是可能的。编译器声明它期望 GoodResource 是 return 类型。我错过了什么,还是我完全以错误的方式解决了这个问题?

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

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

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

目前,SampleProcessingFunction return 每个分支有两种 不同的 类型。

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

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

您可能会问 "why can't the compiler figure out the correct case automatically",但是如果您的 DU 有两个 相同 类型的案例会怎样?例如:

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"

{ 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" }