@@ -712,6 +712,22 @@ error, and if @racket[xs] is infinitely long, @racket[init!] will never return.
712712 (init! {1 :: 2 :: 3 :: Nil})
713713 (eval:error (init! (: Nil (t:List t:Integer)))))}
714714
715+ @defproc[(inits [xs (t:List a)]) (t:List (t:List a))]{
716+
717+ Returns a list of the inital segments of @racket[xs].
718+
719+ @(hackett-examples
720+ (inits {1 :: 2 :: 3 :: Nil})
721+ (inits (: Nil (t:List t:Integer))))}
722+
723+ @defproc[(tails [xs (t:List a)]) (t:List (t:List a))]{
724+
725+ Returns a list of the terminal segments of @racket[xs].
726+
727+ @(hackett-examples
728+ (tails {1 :: 2 :: 3 :: Nil})
729+ (tails (: Nil (t:List t:Integer))))}
730+
715731@defproc[(uncons [xs (t:List a)]) (t:Maybe (t:Tuple a (t:List a)))]{
716732
717733When @racket[xs] is @racket[Nil], @racket[uncons xs] is @racket[Nothing]. Otherwise, if @racket[xs]
@@ -757,6 +773,16 @@ Produces a list with the first @racket[n] elements of @racket[xs]. If @racket[xs
757773 (take 2 {1 :: Nil})
758774 (take 2 (: Nil (t:List t:Integer))))}
759775
776+ @defproc[(take-while [p {a t:-> t:Bool}] [xs (t:List a)]) (t:List a)]{
777+
778+ Returns the longest initial segment of @racket[xs] such that every element satisfies @racket[p].
779+
780+ @(hackett-examples
781+ (take-while (λ [x] {(remainder! x 2 ) == 1 }) {1 :: 3 :: 6 :: 9 :: Nil})
782+ (let ([is-just (maybe False (const True))])
783+ (take-while is-just {(Just 1 ) :: (Just 2 ) :: Nothing :: (Just 3 ) :: Nil}))
784+ (take-while (λ [x] {(remainder! x 2 ) == 0 }) (: Nil (t:List t:Integer))))}
785+
760786@defproc[(drop [n t:Integer] [xs (t:List a)]) (t:List a)]{
761787
762788Produces a list like @racket[xs] without its first @racket[n] elements. If @racket[xs] contains fewer
@@ -767,6 +793,69 @@ then @racket[n] elements, the result is @racket[Nil].
767793 (drop 2 {1 :: Nil})
768794 (drop 2 (: Nil (t:List t:Integer))))}
769795
796+ @defproc[(drop-while [p {a t:-> t:Bool}] [xs (t:List a)]) (t:List a)]{
797+
798+ Returns the longest terminal segment of @racket[xs] which is either @racket[Nil] or starts with an
799+ element @racket[x] such that @racket[(not (p x))].
800+
801+ @(hackett-examples
802+ (drop-while (λ [x] {(remainder! x 2 ) == 1 }) {1 :: 3 :: 6 :: 9 :: Nil})
803+ (let ([is-just (maybe False (const True))])
804+ (drop-while is-just {(Just 1 ) :: (Just 2 ) :: Nothing :: (Just 3 ) :: Nil}))
805+ (drop-while (λ [x] {(remainder! x 2 ) == 0 }) (: Nil (t:List t:Integer))))}
806+
807+ @defproc[(nth [xs (t:List a)] [n t:Integer]) (t:Maybe a)]{
808+
809+ Returns @racket[Just] the nth element of @racket[xs] if it exists, starting at 0 , and
810+ @racket[Nothing] if it doesn't.
811+
812+ @(hackett-examples
813+ (nth {1 :: 2 :: 3 :: Nil} 2 )
814+ (nth {1 :: 2 :: 3 :: Nil} -1 )
815+ (nth {1 :: Nil} 2 )
816+ (nth (: Nil (t:List t:Integer)) 2 ))}
817+
818+ @defproc[(nth! [xs (t:List a)] [n t:Integer]) a]{
819+
820+ Returns the nth element of @racket[xs], starting at 0. This function is
821+ @tech[#:key "partial function " ]{partial}, because it errors when @racket[{n >= (length xs)}].
822+
823+ @(hackett-examples
824+ (nth! {1 :: 2 :: 3 :: Nil} 2 )
825+ (eval:error (nth! {1 :: 2 :: 3 :: Nil} -1 ))
826+ (eval:error (nth! {1 :: Nil} 2 ))
827+ (eval:error (nth! (: Nil (t:List t:Integer)) 2 )))}
828+
829+ @defproc[(find-index [p {a t:-> Bool}] [xs (t:List a)]) (t:Maybe t:Integer)]{
830+
831+ Finds the first element of @racket[xs] which satisfies @racket[p], and returns @racket[Just] its
832+ index. If there is no such element, the function returns @racket[Nothing].
833+
834+ @(hackett-examples
835+ (find-index (λ [x] {(remainder! x 2 ) == 0 }) {1 :: 2 :: 3 :: Nil})
836+ (find-index (λ [x] {x < 0 }) {1 :: 2 :: 3 :: Nil})
837+ (find-index (const True) (: Nil (t:List t:Integer))))}
838+
839+ @defproc[(index-of [_ (Eq a)] [x a] [xs (t:List a)]) (t:Maybe t:Integer)]{
840+
841+ Finds the first occurrence of @racket[x] in @racket[xs] and returns @racket[Just] its index. If
842+ @racket[x] is not contained in @racket[xs], the function returns @racket[Nothing]. This is
843+ equivalent to @racket[(find-index (== x) xs)].
844+
845+ @(hackett-examples
846+ (index-of 2 {1 :: 2 :: 3 :: Nil})
847+ (index-of -1 {1 :: 2 :: 3 :: Nil})
848+ (index-of 2 Nil))}
849+
850+ @defproc[(find [p {a t:-> t:Bool}] [xs (t:List a)]) (t:Maybe a)]{
851+
852+ Returns @racket[Just] the first element @racket[_x] of @racket[xs] such that @racket[(p _x)] is
853+ @racket[True]. If no element in @racket[xs] satisfies @racket[p], @racket[Nothing] is returned.
854+
855+ @(hackett-examples
856+ (find (λ [x] {x > 5 }) {3 :: 7 :: 2 :: 9 :: 12 :: 4 :: Nil})
857+ (find (λ [x] {x > 5 }) {1 :: 2 :: 3 :: Nil}))}
858+
770859@defproc[(filter [f {a t:-> t:Bool}] [xs (t:List a)]) (t:List a)]{
771860
772861Produces a list that contains each element, @racket[_x], for which @racket[_x] is an element of
@@ -808,6 +897,37 @@ the following expression:
808897 (foldl * 1 {1 :: 2 :: 3 :: 4 :: 5 :: Nil})
809898 (foldl - 0 {1 :: 2 :: 3 :: 4 :: 5 :: Nil}))}
810899
900+ @defproc[(unfoldr [step {b t:-> (t:Maybe (t:Tuple a b))}] [seed b]) (t:List a)]{
901+
902+ @racket[unfoldr] constructs a list from an initial value, stopping when @racket[(step seed)] is
903+ @racket[Nothing]. In a certain way, @racket[unfoldr] acts as a dual to @racket[foldr]. More
904+ specifically, @racket[{(unfoldr g (foldr f z xs)) == xs}] when @racket[{(g z) == Nothing}] and
905+ @racket[{(g (f x y)) == (Just (tuple x y))}] for any @racket[x] in @racket[xs].
906+
907+ @(hackett-examples
908+ (unfoldr (λ [x] (if {x == 1 } Nothing
909+ (Just (Tuple (show x) (quotient! x 2 )))))
910+ 128 )
911+ (take 5 (unfoldr (λ [x] (Just (Tuple x {x + 2 }))) 0 )))}
912+
913+ @defproc[(concat [_ (Monoid m)] [ms (t:List m)]) m]{
914+ Returns the result of appending each element of @racket[ms] together. Equivalent to
915+ @racket[(foldr ++ mempty)].
916+
917+ @(hackett-examples
918+ (eval:check (concat {"a " :: "b " :: "c " :: Nil}) "abc " )
919+ (eval:check (concat {{1 :: Nil} :: {2 :: 3 :: Nil} :: {4 :: 5 :: 6 :: Nil} :: Nil})
920+ (:: 1 (:: 2 (:: 3 (:: 4 (:: 5 (:: 6 Nil))))))))}
921+
922+ @defproc[(fold-map [_ (Monoid m)] [f {a t:-> m}] [xs (List a)]) m]{
923+
924+ Applies @racket[f] to each element of @racket[xs] and concatenates each resulting list. Equivalent
925+ to @racket[=<<] when @racket[m] is @racket[(List b)] for some @racket[b].
926+
927+ @(hackett-examples
928+ (fold-map show {1 :: 2 :: 3 :: Nil})
929+ (fold-map tail {{1 :: Nil} :: Nil :: {2 :: 3 :: Nil} :: {4 :: 5 :: 6 :: Nil} :: Nil}))}
930+
811931@defproc[(sum [xs (t:List t:Integer)]) t:Integer]{
812932
813933Adds the elements of @racket[xs] together and returns the sum. Equivalent to @racket[(foldl + 0 )].
@@ -816,6 +936,23 @@ Adds the elements of @racket[xs] together and returns the sum. Equivalent to @ra
816936 (eval:check (sum {1 :: 2 :: 3 :: Nil}) 6 )
817937 (eval:check (sum Nil) 0 ))}
818938
939+ @defproc[(product [xs (t:List t:Integer)]) t:Integer]{
940+
941+ Multiplies the elements of @racket[xs] together and returns the product. Equivalent to
942+ @racket[(foldl * 1 )].
943+
944+ @(hackett-examples
945+ (eval:check (product {1 :: 2 :: 3 :: 4 :: Nil}) 24 )
946+ (eval:check (product Nil) 1 ))}
947+
948+ @defproc[(iterate [step {a t:-> a}] [seed a]) (List a)]{
949+
950+ Returns the infinite list @racket[{seed :: (step seed) :: (step (step seed)) :: ... }].
951+
952+ @(hackett-examples
953+ (take 5 (iterate (+ 1 ) 0 ))
954+ (take 5 (iterate (λ [x] {x ++ "a " }) "" )))}
955+
819956@defproc[(reverse (xs (t:List a))) (t:List a)]{
820957
821958Returns @racket[xs] in reversed order.
@@ -828,7 +965,7 @@ Returns @racket[xs] in reversed order.
828965
829966This function will apply @racket[f] to each element in @racket[as] and @racket[bs] until it
830967has reached the end of either, then it returns a list like
831- @racket[{f _a0 _b0 :: f _a1 _b1 :: f _a2 _b2 :: ... :: Nil}] (where @racket[as] contains
968+ @racket[{( f _a0 _b0) :: ( f _a1 _b1) :: ( f _a2 _b2) :: ... :: Nil}] (where @racket[as] contains
832969elements named @racket[_a0], @racket[_a1], @racket[_a2] etc., and @racket[bs] contains elements
833970named @racket[_b0], @racket[_b1], @racket[_b2] etc.).
834971
@@ -857,11 +994,18 @@ Returns an infinite list containing only @racket[x].
857994@(hackett-examples
858995 (take 5 (repeat 1 )))}
859996
997+ @defproc[(replicate [n Integer] [x a]) (t:List a)]{
998+
999+ Returns a list of @racket[n] copies of @racket[x].
1000+
1001+ @(hackett-examples
1002+ (replicate 3 1 ))}
1003+
8601004@defproc[(cycle! [xs (t:List a)]) (t:List a)]{
8611005
8621006Returns the infinite list @racket[{xs ++ xs ++ xs ++ ... }]. If @racket[xs] is infinite,
863- @racket[cycle! xs == xs]. This function is @tech[#:key "partial function " ]{partial},
864- because it errors when given @racket[Nil].
1007+ @racket[{( cycle! xs) or == xs} ]. This function is @tech[#:key "partial function " ]{partial}, because it
1008+ errors when given @racket[Nil].
8651009
8661010@(hackett-examples
8671011 (take 10 (cycle! {1 :: 2 :: 3 :: Nil}))
@@ -871,8 +1015,8 @@ because it errors when given @racket[Nil].
8711015
8721016Logically ors the elements of @racket[xs] together and returns the result. Equivalent to @racket[(foldr || False)].
8731017Because it uses a right fold, the only elements which will be evaluated are those before the first expression which
874- evaluates to @racket[True]. Additionally, @racket[or infinite-list] can never return @racket[False], and
875- @racket[or (repeat False)] will never terminate.
1018+ evaluates to @racket[True]. Additionally, @racket[( or infinite-list) ] can never return @racket[False], and
1019+ @racket[( or (repeat False) )] will never terminate.
8761020
8771021@(hackett-examples
8781022 (or {True :: False :: Nil})
@@ -884,8 +1028,8 @@ evaluates to @racket[True]. Additionally, @racket[or infinite-list] can never re
8841028
8851029Logically ands the elements of @racket[xs] together and returns the result. Equivalent to @racket[(foldr && True)].
8861030Because it uses a right fold, the only elements which will be evaluated are those before the first expression which
887- evaluates to @racket[False]. Additionally, @racket[and infinite-list] can never return @racket[True], and
888- @racket[and (repeat True)] will never terminate.
1031+ evaluates to @racket[False]. Additionally, @racket[( and infinite-list) ] can never return @racket[True], and
1032+ @racket[( and (repeat True) )] will never terminate.
8891033
8901034@(hackett-examples
8911035 (and {True :: False :: Nil})
@@ -947,6 +1091,7 @@ in @racket[xs] will be checked for equality.
9471091
9481092@(hackett-examples
9491093 (delete 2 {1 :: 2 :: 3 :: Nil})
1094+ (delete 2 {1 :: 2 :: 3 :: 2 :: Nil})
9501095 (delete 0 {1 :: 2 :: 3 :: Nil})
9511096 (head (delete 1 {1 :: 2 :: (error! "never happens " ) :: Nil}))
9521097 (delete 1 Nil))}
@@ -960,13 +1105,14 @@ such @racket[y] will be checked for equality.
9601105@(hackett-examples
9611106 (delete-by > 2 {1 :: 2 :: 3 :: Nil})
9621107 (delete-by > 0 {1 :: 2 :: 3 :: Nil})
963- (head (delete-by not = 1 {1 :: 2 :: (error! "never happens " ) :: Nil}))
1108+ (head (delete-by / = 1 {1 :: 2 :: (error! "never happens " ) :: Nil}))
9641109 (delete-by (λ [y x] {(remainder! y x) == 0 }) 2 Nil)
9651110 (delete-by (error! "never happens " ) (error! "never happens " ) (: Nil (t:List t:Integer))))}
9661111
9671112@defproc[(intersperse [x a] [xs (t:List a)]) (t:List a)]{
9681113
969- Given a separator and a list, intersperse intersperses the separator between each element of the list.
1114+ Given a separator and a list, intersperse returns a new list with the separator placed between each
1115+ element of the list.
9701116
9711117@(hackett-examples
9721118 (intersperse 42 {1 :: 2 :: 3 :: Nil})
@@ -1035,9 +1181,14 @@ evaluated, produces the value.
10351181@subsection[#:tag "reference-equality " ]{Equality}
10361182
10371183@defclass[(t:Eq a)
1038- [== {a t:-> a t:-> t:Bool}]]{
1184+ [== {a t:-> a t:-> t:Bool}]
1185+ [/= {a t:-> a t:-> t:Bool}]]{
10391186The class of types with a notion of equality. The @racket[== ] method should produce @racket[True] if
1040- both of its arguments are equal, otherwise it should produce @racket[False].
1187+ both of its arguments are equal, otherwise it should produce @racket[False]. The @racket[/=]
1188+ method should produce @racket[True] if its arguments are unequal, otherwise it should produce
1189+ @racket[False]. Default implementations of @racket[== ] and @racket[/=] are given in terms of the
1190+ negation of the other, in case inequality is easier to define than equality, or if it is more
1191+ efficient to implement independent definitions for each.
10411192
10421193@defmethod[== {a t:-> a t:-> t:Bool}]{
10431194
@@ -1046,7 +1197,16 @@ both of its arguments are equal, otherwise it should produce @racket[False].
10461197 (eval:check {10 == 11 } False)
10471198 (eval:check {{1 :: 2 :: Nil} == {1 :: 2 :: Nil}} True)
10481199 (eval:check {{1 :: 2 :: Nil} == {1 :: Nil}} False)
1049- (eval:check {{1 :: 2 :: Nil} == {1 :: 3 :: Nil}} False))}}
1200+ (eval:check {{1 :: 2 :: Nil} == {1 :: 3 :: Nil}} False))}
1201+
1202+ @defmethod[/= {a t:-> a t:-> t:Bool}]{
1203+
1204+ @(hackett-examples
1205+ (eval:check {10 /= 10 } False)
1206+ (eval:check {10 /= 11 } True)
1207+ (eval:check {{1 :: 2 :: Nil} /= {1 :: 2 :: Nil}} False)
1208+ (eval:check {{1 :: 2 :: Nil} /= {1 :: Nil}} True)
1209+ (eval:check {{1 :: 2 :: Nil} /= {1 :: 3 :: Nil}} True))}}
10501210
10511211@subsection[#:tag "reference-semigroup-monoid " ]{Semigroups and monoids}
10521212
0 commit comments