2015-04-22 13 views
10

mam następujące typy:F # - Czy mogę zwrócić dyskryminowanych unii z funkcji

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


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

Mam następujący dyskryminowanych UNION:

type ProcessingResult = 
    | Good of GoodResource 
    | Error of ErrorResource 

Następnie chcesz mieć funkcję, która będzie miała typ zwrotu dyskryminowanego związku ProcessingResult:

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

Czy staram się robić to, co możliwe. Kompilator podaje, że oczekuje, że GoodResource będzie typem zwracanym. Czego mi brakuje lub czy całkowicie podchodzę do tego w niewłaściwy sposób?

Odpowiedz

16

W obecnej SampleProcessingFunction zwraca dwa różne typów dla każdego oddziału.

Aby przywrócić samą typu, trzeba stworzyć DU (co robiłeś), ale również określić przypadek DU wyraźnie, jak to:

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

Można zapytać „dlaczego” t kompilator automatycznie wykrywa poprawny przypadek ", ale co się stanie, jeśli twój DU ma dwa przypadki tego samego typu? Na przykład:

type GoodOrError = 
    | Good of string 
    | Error of string 

w poniższym przykładzie, kompilator nie może określić, jakie sprawa chodziło Ci o:

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

Więc znowu trzeba użyć konstruktora w przypadku, gdy chcesz:

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

Musisz podać przypadek typu unii, który chcesz zwrócić w dowolnym oddziale.

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

Proponuję przeczytać ten znakomite artykuły Scott Wlaschin Railway Oriented Programming

7

{ Id = 123; Field1 = "field1data" } to wartość typu GoodResource, nie typu ProcessingResult. Aby utworzyć wartość typu ProcessingResult, należy użyć jednego z dwóch konstruktorów: Good lub Error.

Więc funkcja może być napisane tak:

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