Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Result bind with different types?

Tags:

f#

I've made a simple Computation Expression workflow for dealing with Results.

[<RequireQualifiedAccess>]
module Result =

    type Builder() =

        member __.Bind(x, f) = x |> Result.bind f

        member __.Return(x) = x

        member __.ReturnFrom(x) = Ok x

    let workflow = Builder()

I also use different types to represent different kids of errors:

type ValidationError<'a> = { Obj:'a; Message:string }
type InvalidOperationError = { Operation:string; Message:string }

The problem arises when two results have different error types.

LetterString.create : string -> Result<LetterString, ValidationError<string>>
Username.create : string -> Result<Username, ValidationError<string>>
PositiveDecimal.create : decimal -> Result<PositiveDecimal, ValidationError<decimal>>
let user = 
    Result.workflow {
        let! name = LetterString.create "Tom"
        let! username = Username.create "Tom01098"
        // Error occurs here.
        let! balance = PositiveDecimal.create 100m

        return! { 
            // User record creation elided.
        }
    }
FS0001  Type mismatch. Expecting a
    'Result<PositiveDecimal,ValidationError<string>>'    
but given a
    'Result<PositiveDecimal,ValidationError<decimal>>'

I have already tried using a DU type of all errors:

type Error<'a> =
    | ValidationError of Obj:'a * Message:string
    | InvalidOperationError of Operation:string * Message:string

This has a similar problem when the generic parameter 'a is different between errors. It also loses the exact type of error in the type signature of the function.

The expected result is that the entire workflow has a unified error type, preferably as specific as possible in terms of type.

like image 238
Tom01098 Avatar asked May 28 '26 00:05

Tom01098


1 Answers

Can be solved by removing the generic parameter and using a single Error DU. Unfortunately this loses the signature I wanted, but it will have to do.

like image 95
Tom01098 Avatar answered May 31 '26 22:05

Tom01098



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!