import { Chainable } from './chain' ; import { HKTFrom , ReplaceFirst , Type , TypeFromHKT , URIS } from './hkt' ; type KleisliFunction < URI extends URIS , A , B > = ( value : A ) => Chainable < URI , ReplaceFirst < any , B > > ; type KleisiInfo = { Monad : Chainable < any , any > ; URI : URIS ; Generics : any [ ] ; A : any ; } ; type getKleisiInfo < T extends ( ... args : any ) => Chainable < any , any > , Monad extends Chainable < any , any > = ReturnType < T > , URI extends URIS = Monad [ '_URI' ] , Generics extends any [ ] = Monad [ '_A' ] , A = Monad [ '_A' ] [ 0 ] > = { Monad : Monad ; URI : URI ; Generics : Generics ; A : A ; } ; export function kleisli < func1 extends ( ... args : any ) => Chainable < any , any > , info extends KleisiInfo = getKleisiInfo < func1 > > ( a ) ; export function kleisli < func1 extends ( ... args : any ) => Chainable < any , any > , info extends KleisiInfo = getKleisiInfo < func1 > , B = any > ( a , b ) ; export function kleisli < func1 extends ( ... args : any ) => Chainable < any , any > , info extends KleisiInfo = getKleisiInfo < func1 > , B = any , C = any > ( a , b , c ) ; export function kleisli < func1 extends ( ... args : any ) => Chainable < any , any > , info extends KleisiInfo = getKleisiInfo < func1 > , B = any , C = any , D = any > ( a , b , c , d ) ; export function kleisli < func1 extends ( ... args : any ) => Chainable < any , any > , info extends KleisiInfo = getKleisiInfo < func1 > , B = any , C = any , D = any , E = any > ( a , b , c , d , e ) ; export function kleisli < func1 extends ( ... args : any ) => Chainable < any , any > , info extends KleisiInfo = getKleisiInfo < func1 > , B = any , C = any , D = any , E = any , F = any > ( a , b , c , d , e , f ) ; export function kleisli < T extends KleisliFunction < any , any , any > [ ] , M extends Chainable < any , any > = ReturnType < T [ 0 ] > > ( ... fns ) { const [ head , ... rest ] = fns ; return ( ... args ) : Type < M [ '_URI' ] , any > => { return rest . reduce ( ( prev , cur ) => prev . chain ( cur ) , ( head as any ) ( ... args ) ) ; } ; }