import { NoInfer } from 'Function/_api' ; import { HKT , ReplaceFirst , ReplaceFirstAndReplaceSecondIfSecondIsNever , ReplaceFirstAndSecond , Type , URIS } from './hkt' ; import { FunctorKind } from './map' ; export interface MonadKind < F extends URIS , A extends any [ ] > extends FunctorKind < F , A > { readonly chain : < B > ( f : ( a : A [ 0 ] ) => Type < F , ReplaceFirst < A , B > > ) => Type < F , ReplaceFirst < A , B > > ; } export interface Chainable < F extends URIS , A extends any [ ] > extends HKT < F , A > { readonly chain : < B > ( f : ( a : A [ 0 ] ) => Type < F , ReplaceFirstAndReplaceSecondIfSecondIsNever < A , B , never > > ) => Type < F , ReplaceFirst < A , B > > ; } export const chain = < Monad extends Chainable < any , any > , URI extends URIS = Monad [ '_URI' ] , Generics extends any [ ] = Monad [ '_A' ] , B = any > ( f ) => ( fa ) : Type < URI , ReplaceFirst < Generics , B > > => { return fa . chain ( f ) ; } ; example export const chainFlex = < Monad extends Chainable < any , any > , URI extends URIS = Monad [ '_URI' ] , B = any , C = any > ( f ) => ( fa ) : Type < URI , ReplaceFirstAndSecond < Monad [ '_A' ] , B , Monad [ '_A' ] [ 1 ] | C > > => { return fa . chain ( f ) ; } ;