Edit: See this comment for more concise question and the answer to it.
I've got a delightful stack of monad transformers here:
type Operation<'TResult, 'TError> = ReaderT<SqlConnection * SqlTransaction, ResultT<Async<Result<'TResult, 'TError list>>>>
and it works well working with it in computation expressions.
let run
(get : 'TSubject -> Operation<'TState, 'TAppError>)
(subj : 'TSubject) : Operation<unit, 'TAppError> = monad {
let! state = get subj |> map (fun x -> x)
return ()
}
x here is 'TState which is lovely that map lifts that lambda all the way. However how do I do maps somewhere within the stack? Like transform the error type, represented here by transformToCommonErrorTypeN:
let run
(get : 'TSubject -> Operation<'TState, 'TAppError>)
(set : 'TState -> Operation<'TState, 'TOtherError>)
(subj : 'TSubject) : Operation<unit, 'TError> = monad {
let! state = get subj |> transformToCommonErrorType1
let state = state // ... interpret new state
do! set subj state |> transformToCommonErrorType2
return ()
}
Given a function
'TAppError -> 'TError,
how do I lift that to a
Operation<'TResult, 'TAppError> -> Operation<'TResult, 'TError>
(i.e. ReaderT<SqlConnection * SqlTransaction, ResultT<Async<Result<'TResult, 'TAppError list>>>> -> ReaderT<SqlConnection * SqlTransaction, ResultT<Async<Result<'TResult, 'TError list>>>>.)
So far I have:
// AppError :: 'TAppError -> 'TError`
let! state = get subj |> (AppError |> List.map |> mapError |> Async.map |> ResultT.??? |> ReaderT.map)
but I'm not sure what I need at the ResultT.??? bit...
Side note: ResultT.map has an odd return type to my eye. Is ResultT<'``Monad<'Result<('T -> 'U),'E>>``> correct, or a mistaken type parameter name?
Edit: See this comment for more concise question and the answer to it.
I've got a delightful stack of monad transformers here:
and it works well working with it in computation expressions.
xhere is'TStatewhich is lovely that map lifts that lambda all the way. However how do I do maps somewhere within the stack? Like transform the error type, represented here bytransformToCommonErrorTypeN:Given a function
'TAppError -> 'TError,how do I lift that to a
Operation<'TResult, 'TAppError> -> Operation<'TResult, 'TError>(i.e.
ReaderT<SqlConnection * SqlTransaction, ResultT<Async<Result<'TResult, 'TAppError list>>>> -> ReaderT<SqlConnection * SqlTransaction, ResultT<Async<Result<'TResult, 'TError list>>>>.)So far I have:
but I'm not sure what I need at the
ResultT.???bit...Side note: ResultT.map has an odd return type to my eye. Is
ResultT<'``Monad<'Result<('T -> 'U),'E>>``>correct, or a mistaken type parameter name?