2015-04-22 9 views
10

Ich habe folgende Typen:F # - Kann ich zurück eine diskriminierte Vereinigung aus einer Funktion

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


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

Ich habe folgende diskriminiert Vereinigung:

type ProcessingResult = 
    | Good of GoodResource 
    | Error of ErrorResource 

wollen Sie dann eine Funktion haben, die haben ein Rückgabetyp der diskriminierten Vereinigung ProcessingResult:

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

Ist das, was ich möglich zu tun versuchen. Der Compiler gibt an, dass erwartet wird, dass GoodResource der Rückgabetyp ist. Was vermisse ich oder mache ich das völlig falsch?

Antwort

16

zu lesen Wie es aussieht, SampleProcessingFunction kehrt zwei verschiedene Typen für jeden Zweig.

Rückkehr der gleichen Typ, benötigen Sie einen DU erstellen (was Sie getan haben), sondern auch den Fall des DU explizit angeben, wie folgt aus:

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

Sie könnten „fragen, warum kann‘ t der Compiler den richtigen Fall automatisch herausfinden ", aber was passiert, wenn Ihr DU zwei Fälle des selben Typs hat? Zum Beispiel:

type GoodOrError = 
    | Good of string 
    | Error of string 

Im Beispiel unten, kann der Compiler nicht bestimmen, welcher Fall Sie nach:

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

Also noch einmal müssen Sie den Konstruktor für den Fall, verwenden Sie wollen:

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

Sie müssen den Fall des Unionstyps angeben, den Sie in beiden Zweigen zurückgeben möchten.

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

Ich schlage vor, diesen ausgezeichneten Artikel von Scott Wlaschin Railway Oriented Programming

7

{ Id = 123; Field1 = "field1data" } ist ein Wert vom Typ GoodResource, nicht vom Typ ProcessingResult. Um einen Wert vom Typ ProcessingResult zu erstellen, müssen Sie einen der beiden Konstruktoren Good oder Error verwenden.

So können Sie Ihre Funktion wie folgt geschrieben werden:

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