: first4 ( seq -- first second third fourth )
3 swap bounds-check nip first4-unsafe ; inline
+: ??nth ( n seq -- elt/f ? )
+ 2dup bounds-check? [ nth-unsafe t ] [ 2drop f f ] if ; inline
+
: ?nth ( n seq -- elt/f )
- 2dup bounds-check? [ nth-unsafe ] [ 2drop f ] if ; inline
+ ??nth drop ; inline
: ?set-nth ( elt n seq -- )
2dup bounds-check? [ set-nth-unsafe ] [ 3drop ] if ; inline
+: ?nth-of ( seq n -- elt/f ) swap ?nth ; inline
+
+: ??nth-of ( seq n -- elt ? ) swap ??nth ; inline
+
: index-or-length ( seq n -- seq n' ) over length min ; inline
: index-of-last ( seq -- n seq ) [ length 1 - ] keep ; inline
{ } [ - . ] each-prior
] unit-test
+{ } [
+ 1000 { } [ - . ] each-prior-from
+] unit-test
+
{ } [
{ 5 16 42 103 } [ - . ] each-prior
] unit-test
+{ } [
+ 1 { 5 16 42 103 } [ - . ] each-prior-from
+] unit-test
+
+
{ { } } [
{ } [ - ] map-prior
] unit-test
{ 0 } [ 0 CHAR: a "abba" nth-index ] unit-test
{ 3 } [ 1 CHAR: a "abba" nth-index ] unit-test
{ f } [ 2 CHAR: a "abba" nth-index ] unit-test
+
+{ { -995 11 26 61 } } [
+ 1000 V{ 5 16 42 103 } [ - ] { } map-prior-identity-as
+] unit-test
[ [ push ] curry compose 3nested-each ] keep
] keep like ; inline
-: each-prior ( ... seq quot: ( ... prior elt -- ... ) -- ... )
+: prev ( n seq -- obj ) [ 1 - ] dip nth ; inline
+: ?prev ( n seq -- obj/f ) [ 1 - ] dip ?nth ; inline
+: ??prev ( n seq -- obj/f ? ) [ 1 - ] dip ??nth ; inline
+: prev-of ( seq n -- obj ) 1 - nth-of ; inline
+: ?prev-of ( seq n -- obj/f ) 1 - ?nth-of ; inline
+: ??prev-of ( seq n -- obj/f ) 1 - ??nth-of ; inline
+
+: prev-identity ( i seq -- identity i seq )
+ 2dup ??prev [ drop 0 ] unless -rot ; inline
+
+: each-prior-identity-from ( ... identity i seq quot: ( ... prior elt -- ... ) -- ... )
'[ [ swap @ ] keep ]
- sequence-operator 0 -rot each-integer-from drop ; inline
+ length-operator each-integer-from drop ; inline
-: map-prior-as ( ... seq quot: ( ... prior elt -- elt' ) exemplar -- seq' )
+: each-prior-from ( ... i seq quot: ( ... prior elt -- ... ) -- ... )
+ [ prev-identity ] dip each-prior-identity-from ; inline
+
+: each-prior ( ... seq quot: ( ... prior elt -- ... ) -- ... )
+ 0 -rot each-prior-from ; inline
+
+: map-prior-identity-from-as ( ... identity i seq quot: ( ... prior elt -- elt' ) exemplar -- seq' )
[
- '[ [ swap @ ] keep swap ] length-operator 0 -rot
- ] dip map-integers-as nip ; inline
+ '[ [ swap @ ] keep swap ] length-operator
+ ] dip map-integers-from-as nip ; inline
+
+: map-prior-identity-as ( ... identity seq quot: ( ... prior elt -- elt' ) exemplar -- seq' )
+ [ 0 ] 3dip map-prior-identity-from-as ; inline
+
+: map-prior-from-as ( ... i seq quot: ( ... prior elt -- elt' ) exemplar -- seq' )
+ [ prev-identity ] 2dip map-prior-identity-from-as ; inline
+
+: map-prior-as ( ... seq quot: ( ... prior elt -- elt' ) exemplar -- seq' )
+ 0 -roll map-prior-from-as ; inline
+
+: map-prior-from ( ... seq quot: ( ... prior elt -- elt' ) i -- seq' )
+ pick map-prior-from-as ; inline
: map-prior ( ... seq quot: ( ... prior elt -- elt' ) -- seq' )
over map-prior-as ; inline