 
 INSTANCE: hashtable-cursor input-cursor
 
-M: hashtable-cursor cursor-value
+M: hashtable-cursor cursor-value-unsafe
     cursor-key-value 2array ; inline
 
 INSTANCE: hashtable container

INSTANCE: zip-cursor assoc-cursor

M: zip-cursor cursor-key-value
    [ keys>> cursor-value ] [ values>> cursor-value ] bi ; inline

: zip-cursors ( a-begin a-end b-begin b-end -- begin end )
    [ <zip-cursor> ] bi-curry@ bi* ; inline


: 2map ( ... a b quot: ( ... x y -- ... z ) -- ... c )
    pick 2map-as ; inline 

!
! generalized zips
!

: -unzip- ( quot -- quot' )
    '[ [ keys>> cursor-value-unsafe ] [ values>> ] bi @ ] ; inline

MACRO: nzip-cursors ( n -- ) 1 - [ zip-cursors ] n*quot ;

: nall ( seqs... n -- begin end ) [ [ all ] swap napply ] [ nzip-cursors ] bi ; inline

: nall- ( seqs... quot n -- begin end quot ) swap [ nall ] dip ; inline

MACRO: -ncontainer- ( n -- )
    1 - [ -unzip- ] n*quot [ -container- ] prepend ;

: ncontainer- ( seqs... quot n -- begin end quot ) [ nall- ] [ -ncontainer- ] bi ; inline

: neach ( seqs... quot n -- ) ncontainer- -each ; inline
: nmap-as ( seqs... quot exemplar n -- newseq )
    swap [ ncontainer- ] dip -map-as ; inline
: nmap ( seqs... quot n -- newseq )
    dup [ npick ] curry [ dip swap ] curry dip nmap-as ; inline
