Uwaga
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Typ Result<'T,'TFailure>
umożliwia pisanie kodu odpornego na błędy, który można skomponować.
Składnia
// The definition of Result in FSharp.Core
[<StructuralEquality; StructuralComparison>]
[<CompiledName("FSharpResult`2")>]
[<Struct>]
type Result<'T,'TError> =
| Ok of ResultValue:'T
| Error of ErrorValue:'TError
Uwagi
Result
Zobacz moduł kombinatorów wbudowanych dla elementu Result
. type.
Należy pamiętać, że typ wyniku jest strukturą dyskryminowaną unii. Semantyka równości strukturalnej ma zastosowanie tutaj.
Typ Result
jest zwykle używany w monadycznej obsłudze błędów, która jest często nazywana programowaniem zorientowanym na kolej w społeczności języka F#. Poniższy przykład trywialny pokazuje to podejście.
// Define a simple type which has fields that can be validated
type Request =
{ Name: string
Email: string }
// Define some logic for what defines a valid name.
//
// Generates a Result which is an Ok if the name validates;
// otherwise, it generates a Result which is an Error.
let validateName req =
match req.Name with
| null -> Error "No name found."
| "" -> Error "Name is empty."
| "bananas" -> Error "Bananas is not a name."
| _ -> Ok req
// Similarly, define some email validation logic.
let validateEmail req =
match req.Email with
| null -> Error "No email found."
| "" -> Error "Email is empty."
| s when s.EndsWith("bananas.com") -> Error "No email from bananas.com is allowed."
| _ -> Ok req
let validateRequest reqResult =
reqResult
|> Result.bind validateName
|> Result.bind validateEmail
let test() =
// Now, create a Request and pattern match on the result.
let req1 = { Name = "Phillip"; Email = "phillip@contoso.biz" }
let res1 = validateRequest (Ok req1)
match res1 with
| Ok req -> printfn $"My request was valid! Name: {req.Name} Email {req.Email}"
| Error e -> printfn $"Error: {e}"
// Prints: "My request was valid! Name: Phillip Email: phillip@consoto.biz"
let req2 = { Name = "Phillip"; Email = "phillip@bananas.com" }
let res2 = validateRequest (Ok req2)
match res2 with
| Ok req -> printfn $"My request was valid! Name: {req.Name} Email {req.Email}"
| Error e -> printfn $"Error: {e}"
// Prints: "Error: No email from bananas.com is allowed."
test()
Jak widać, istnieje dość łatwo połączyć ze sobą różne funkcje weryfikacji, jeśli wymusisz ich zwrócenie Result
wszystkich elementów . Dzięki temu można podzielić funkcje takie jak te na małe elementy, które są tak komponowalne, jak potrzebne. Ma to również wartość dodaną wymuszania użycia dopasowania wzorca na końcu rundy walidacji, co z kolei wymusza wyższy stopień poprawności programu.