import { PartialFn , PlaceHolder } from './types' ; import { apply } from '../apply' ; import { curry2 } from '../curry' ; import { curryN } from '../curryN' ; name export const __ = { '@@placeholder' : true } ; const isPlaceholder = ( x ) : x is PlaceHolder => x [ '@@placeholder' ] === true ; name export const partial = curry2 ( ( f , args ) : any => { const fnLength = f . length ; const argsLength = args . length ; if ( fnLength === 0 ) return f ; if ( argsLength === 0 ) return curryN ( fnLength as 2 , f ) ; const placeholderAmount = args . filter ( isPlaceholder ) . length ; const expectedLength = Math . max ( 0 , fnLength - argsLength ) + placeholderAmount ; function partiallyApplied ( ... otherArgs ) { if ( placeholderAmount === 0 ) return apply ( args . concat ( otherArgs ) , f ) ; const combinedArgs = Array ( fnLength ) ; for ( let i = 0 ; i < combinedArgs . length ; ++ i ) combinedArgs [ i ] = isPlaceholder ( args [ i ] ) ? otherArgs . shift ( ) : args [ i ] ; return apply ( combinedArgs . concat ( otherArgs ) , f ) ; } return curryN ( expectedLength as 2 , partiallyApplied ) ; } ) ;