简体   繁体   English

F# - 我可以从函数返回一个有区别的联合

[英]F# - Can I return a discriminated union from a function

I have the following types: 我有以下类型:

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


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

I have the following discriminated union: 我有以下歧视联盟:

type ProcessingResult = 
    | Good of GoodResource
    | Error of ErrorResource

Then want to have a function that will have a return type of the discriminated union ProcessingResult: 然后想要一个具有被区分联合ProcessingResult的返回类型的函数:

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

Is what I am trying to do possible. 是我想做的事情。 The compiler is giving out stating that it expects GoodResource to be the return type. 编译器发出声明它希望GoodResource是返回类型。 What am I missing or am I completely going about this the wrong way? 我错过了什么,或者我是否完全以错误的方式解决这个问题?

As it stands, SampleProcessingFunction returns two different types for each branch. 就目前而言, SampleProcessingFunction为每个分支返回两种不同的类型。

To return the same type, you need to create a DU (which you did) but also specify the case of the DU explicitly, like this: 要返回相同的类型,您需要创建一个DU(您已经这样做),但也要明确指定DU的大小写,如下所示:

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

You might ask "why can't the compiler figure out the correct case automatically", but what happens if your DU has two cases of the same type? 您可能会问“为什么编译器无法自动找出正确的情况”,但如果您的DU有两个相同类型的情况会怎样? For example: 例如:

type GoodOrError = 
    | Good of string
    | Error of string

In the example below, the compiler cannot determine which case you mean: 在下面的示例中,编译器无法确定您的意思是:

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

So again you need to use the constructor for the case you want: 所以你需要使用构造函数来处理你想要的情况:

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

You have to state the case of the union type you want to return in either branch. 您必须说明要在任一分支中返回的联合类型的情况。

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

I suggest to read this excellent articles by Scott Wlaschin Railway Oriented Programming 我建议阅读Scott Wlaschin 铁路编程的这篇优秀文章

{ Id = 123; Field1 = "field1data" } { Id = 123; Field1 = "field1data" } is a value of type GoodResource , not of type ProcessingResult . { Id = 123; Field1 = "field1data" }GoodResource类型的值,而不是ProcessingResult类型的值。 To create a value of type ProcessingResult , you need to use one of its two constructors: Good or Error . 要创建ProcessingResult类型的值,您需要使用其两个构造函数之一: GoodError

So your function can be written like this: 所以你的函数可以像这样写:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM