fsprojects / Chessie

Railway-oriented programming for .NET
http://fsprojects.github.io/Chessie/
The Unlicense
187 stars 43 forks source link

unexpected usage of Trial.either #59

Closed bainewedlock closed 4 years ago

bainewedlock commented 4 years ago

Description

I want to use Chessie for error handling, but Trial.either does not make sense to me.

Repro steps

Try to compile this:

open System
open Chessie.ErrorHandling

type Error =
  | InvalidEmail of string
  | DatabaseError of Exception

let validateEmail (email:string) =
  if email.Contains("@")
  then ok email
  else fail (InvalidEmail "@ is missing")

let sendEmail (email:string) =
  printfn "sending email to %s..." email

let handleError (error:Error) =
  match error with
  | InvalidEmail email -> printfn "bad email: %s" email
  | DatabaseError ex   -> printfn "db error: %A" ex

"hello@world"
|> validateEmail
|> Trial.either sendEmail handleError

Expected behavior

Code should compile. If the email is valid, then sendEmail should be called, else handleError

Actual behavior

Compiler error 1:

Type mismatch. Expecting a
    'string * Error list -> 'a'    
but given a
    'string -> unit'    
The type 'string * Error list' does not match the type 'string'F# Compiler(1)

Compiler error 2:

Type mismatch. Expecting a
    'Error list -> 'a'    
but given a
    'Error -> unit'    
The type 'Error list' does not match the type 'Error'

Known workarounds

If I change the signature of the two functions, it works.

let sendEmail (email:string, errors: Error list) =
  printfn "sending email to %s..." email

let handleError (errors:Error list) =
  for error in errors do
  match error with
  | InvalidEmail email -> printfn "bad email: %s" email
  | DatabaseError ex   -> printfn "db error: %A" ex

But this seems like an unneccessary workaround for me.

1.) Why would I want a (always empty) error list in the success handler?

2.) How could there be more than one error in the failure handler? I was expecting that the Result always contains the first error.

My expectations are based on this article: https://fsharpforfunandprofit.com/posts/recipe-part2/

bainewedlock commented 4 years ago

I guess we can forget that, because it seems that Microsoft.FSharp.Core.Result<,> does exactly the thing I want.