import * as T from 'fp-ts/Task' ; export interface MonadDB { readonly getEmail : ( userId : number ) => T . Task < string > ; readonly updateProfile : ( userId : number , name : string , email : string ) => T . Task < void > ; } export interface MonadEmail { readonly sendEmailChangedNotification : ( newEmail : string , oldEmail : string ) => T . Task < void > ; } export interface UpdateProfileRequest { readonly userId : number ; readonly name : string ; readonly email : string ; } declare const monadDB ; declare const monadEmail ; import { pipe } from 'fp-ts/function' ; /**
 * Restituisce `true` se è stata inviata una notifica
 *
 * In questa versione le dipendenze sono cablate nel codice
 */ export const updateCustomerProfile1 = ( request ) : T . Task < boolean > => pipe ( monadDB . getEmail ( request . userId ) , T . chain ( ( oldEmail ) => pipe ( monadDB . updateProfile ( request . userId , request . name , request . email ) , T . chain ( ( ) => { if ( oldEmail !== request . email ) { return pipe ( monadEmail . sendEmailChangedNotification ( request . email , oldEmail ) , T . map ( ( ) => true ) ) ; } else { return T . of ( false ) ; } } ) ) ) ) ; export declare const updateCustomerProfile2 ; export interface Deps { readonly db : MonadDB ; readonly email : MonadEmail ; } export declare const updateCustomerProfile3 ; import { Reader } from 'fp-ts/Reader' ; export declare const updateCustomerProfile4 ; import * as RT from 'fp-ts/ReaderTask' ; const getEmail = ( userId ) : RT . ReaderTask < Deps , string > => ( e ) => e . db . getEmail ( userId ) ; const updateProfile = ( request ) : RT . ReaderTask < Deps , void > => ( e ) => e . db . updateProfile ( request . userId , request . name , request . email ) ; const sendEmailChangedNotification = ( newEmail , oldEmail ) : RT . ReaderTask < Deps , void > => { return ( e ) => e . email . sendEmailChangedNotification ( newEmail , oldEmail ) ; } ; const updateCustomerProfile5 = ( request ) : RT . ReaderTask < Deps , boolean > => pipe ( getEmail ( request . userId ) , RT . chain ( ( oldEmail ) => pipe ( updateProfile ( request ) , RT . chain ( ( ) => { if ( request . email !== oldEmail ) { return pipe ( sendEmailChangedNotification ( request . email , oldEmail ) , RT . map ( ( ) => true ) ) ; } else { return RT . of ( false ) ; } } ) ) ) ) ; /** scrive dallo standard output */ export const putStrLn = ( message ) : T . Task < void > => ( ) => new Promise ( ( res ) => { res ( console . log ( message ) ) ; } ) ; let _email = 'a@gmail.com' ; const withMessage = < A > ( message , fa ) : T . Task < A > => { return pipe ( putStrLn ( message ) , T . chain ( ( ) => fa ) ) ; } ; const setEmail = ( email ) : T . Task < void > => ( ) => { _email = email ; return Promise . resolve ( undefined ) ; } ; const db = { getEmail : ( userId ) => withMessage ( `getting email for ${ userId }: ${ _email }` , T . of ( _email ) ) , updateProfile : ( _userId , _name , email ) => withMessage ( `updating profile` + ( _email !== email ? ` and changing email from ${ _email } to ${ email }` : '' ) , setEmail ( email ) ) } ; const email = { sendEmailChangedNotification : ( newEmail , _oldEmail ) => putStrLn ( `sending change notification to ${ newEmail }` ) } ; const testDeps = { db , email } ; const program = updateCustomerProfile5 ( { userId : 1 , name : 'foo' , email : 'b@gmail.com' } ) ; program ( testDeps ) ( ) . then ( console . log ) ;