Skip to content

Commit d92d59c

Browse files
Expand data/list
1 parent 2fe14f2 commit d92d59c

File tree

2 files changed

+134
-10
lines changed

2 files changed

+134
-10
lines changed

hackett-doc/scribblings/hackett/reference.scrbl

Lines changed: 93 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -645,7 +645,17 @@ Returns @racket[Just] the first element of a list, or @racket[Nothing] if the li
645645
(head {1 :: 2 :: 3 :: Nil})
646646
(head (: Nil (t:List t:Integer))))}
647647

648-
@defthing[tail (t:forall [a] {(t:List a) t:-> (t:Maybe (t:List a))})]{
648+
@defthing[last (forall [a] {(List a) -> (Maybe a)})]{
649+
650+
Returns @racket[just] the last element of a list, or @racket[nothing] if the list is @racket[nil].
651+
This function is @tech[#:key "partial function"]{partial}, since it diverges on an infinitely long
652+
input, e.g. @racket[(letrec ([ones {1 :: ones}]) (last ones))].
653+
654+
@(hackett-examples
655+
(last {1 :: 2 :: 3 :: nil})
656+
(last (: nil (List Integer))))}
657+
658+
@defthing[tail (forall [a] {(List a) -> (Maybe (List a))})]{
649659

650660
Returns @racket[Just] a list without its first element, or @racket[Nothing] if the list is
651661
@racket[Nil].
@@ -654,7 +664,17 @@ Returns @racket[Just] a list without its first element, or @racket[Nothing] if t
654664
(tail {1 :: 2 :: 3 :: Nil})
655665
(tail (: Nil (t:List t:Integer))))}
656666

657-
@defthing[head! (t:forall [a] {(t:List a) t:-> a})]{
667+
@defthing[init (forall [a] {(List a) -> (Maybe a)})]{
668+
669+
Returns @racket[just] a list without its the last element, or @racket[nothing] if the list is
670+
@racket[nil]. This function is @tech[#:key "partial function"]{partial}, since it diverges on an
671+
infinitely long input, e.g. @racket[(letrec ([ones {1 :: ones}]) (last ones))].
672+
673+
@(hackett-examples
674+
(init {1 :: 2 :: 3 :: nil})
675+
(init (: nil (List Integer))))}
676+
677+
@defthing[head! (forall [a] {(List a) -> a})]{
658678

659679
A @tech[#:key "partial function"]{partial} version of @racket[head] that returns the first element of
660680
a list. If the list is empty, it raises an error.
@@ -663,7 +683,17 @@ a list. If the list is empty, it raises an error.
663683
(head! {1 :: 2 :: 3 :: Nil})
664684
(eval:error (head! (: Nil (t:List t:Integer)))))}
665685

666-
@defthing[tail! (t:forall [a] {(t:List a) t:-> (t:List a)})]{
686+
@defthing[last! (forall [a] {(List a) -> a})]{
687+
688+
A less-safe version of @racket[last] which tries to return the last element of any list. This function
689+
is @tech[#:key "partial function"]{partial}; if the given list is empty, @racket[last!] raises an
690+
error, and if the list is infinitely long, the function wil not return.
691+
692+
@(hackett-examples
693+
(last! {1 :: 2 :: 3 :: nil})
694+
(eval:error (last! (: nil (List Integer)))))}
695+
696+
@defthing[tail! (forall [a] {(List a) -> (List a)})]{
667697

668698
A @tech[#:key "partial function"]{partial} version of @racket[tail] that returns a list without its
669699
first element. If the list is empty, it raises an error.
@@ -672,23 +702,70 @@ first element. If the list is empty, it raises an error.
672702
(tail! {1 :: 2 :: 3 :: Nil})
673703
(eval:error (tail! (: Nil (t:List t:Integer)))))}
674704

675-
@defproc[(take [n t:Integer] [xs (t:List a)]) (t:List a)]{
705+
@defthing[init! (forall [a] {(List a) -> a})]{
706+
707+
A less-safe version of @racket[init] which tries to return the last element of any list. This function
708+
is @tech[#:key "partial function"]{partial}; if the given list is empty, @racket[init!] raises an
709+
error, and if the list is infinitely long, the function wil not return.
710+
711+
@(hackett-examples
712+
(init! {1 :: 2 :: 3 :: nil})
713+
(eval:error (init! (: nil (List Integer)))))}
714+
715+
@defthing[uncons (forall [a] {(List a) -> (Maybe (Tuple a (List a)))})]{
716+
717+
Returns @racket[nothing] if the list is @racket[nil], and @racket[just] a pair of the list's first
718+
element and the rest of it otherwise.
719+
720+
@(hackett-examples
721+
(uncons {1 :: 2 :: 3 :: nil})
722+
(uncons (: nil (List Integer))))}
723+
724+
@defthing[uncons! (forall [a] {(List a) -> (Tuple a (List a))})]{
725+
726+
A @tech[#:key "partial function"]{partial} version of @racket[uncons] that returns a pair of the
727+
list's first element and the rest of it. If the list is empty, it raises an error.
728+
729+
@(hackett-examples
730+
(uncons! {1 :: 2 :: 3 :: nil})
731+
(eval:error (uncons! (: nil (List Integer)))))}
732+
733+
@defthing[null? (forall [a] {(List a) -> Bool})]{
734+
735+
This predicate is @racket[true] when its argument is of the form @racket[nil], and is false otherwise.
736+
737+
@(hackett-examples
738+
(null? {1 :: 2 :: 3 :: nil})
739+
(null? (: nil (List Integer))))}
740+
741+
@defthing[length (forall [a] {(List a) -> Integer})]
742+
743+
Returns the length of a finite list. Since the function will diverge on an infinitely long input,
744+
@racket[length] is @tech[#:key "partial function"]{partial}.
745+
746+
@(hackett-examples
747+
(length {1 :: 2 :: 3 :: nil})
748+
(length (: nil (List Integer))))}
749+
750+
@defproc[(take [n Integer] [xs (List a)]) (List a)]{
676751

677752
Produces a list with the first @racket[n] elements of @racket[xs]. If @racket[xs] contains fewer than
678753
@racket[n] elements, @racket[xs] is returned unmodified.
679754

680755
@(hackett-examples
681-
(take 2 {1 :: 2 :: 3 :: Nil})
682-
(take 2 {1 :: Nil}))}
756+
(take 2 {1 :: 2 :: 3 :: nil})
757+
(take 2 {1 :: nil})
758+
(take 2 (: nil (List Integer))))}
683759

684760
@defproc[(drop [n t:Integer] [xs (t:List a)]) (t:List a)]{
685761

686762
Produces a list like @racket[xs] without its first @racket[n] elements. If @racket[xs] contains fewer
687763
then @racket[n] elements, the result is @racket[Nil].
688764

689765
@(hackett-examples
690-
(drop 2 {1 :: 2 :: 3 :: Nil})
691-
(drop 2 {1 :: Nil}))}
766+
(drop 2 {1 :: 2 :: 3 :: nil})
767+
(drop 2 {1 :: nil})
768+
(drop 2 (: nil (List Integer))))}
692769

693770
@defproc[(filter [f {a t:-> t:Bool}] [xs (t:List a)]) (t:List a)]{
694771

@@ -739,6 +816,14 @@ Adds the elements of @racket[xs] together and returns the sum. Equivalent to @ra
739816
(eval:check (sum {1 :: 2 :: 3 :: Nil}) 6)
740817
(eval:check (sum Nil) 0))}
741818

819+
@defthing[intersperse (forall [a] {a -> (List a) -> (List a)})]{
820+
821+
Given a separator and a list, intersperse intersperses the separator between each element of the list.
822+
823+
@(hackett-examples
824+
(intersperse 42 {1 :: 2 :: 3 :: nil})
825+
(intersperse 42 nil))}
826+
742827
@section[#:tag "reference-typeclasses"]{Typeclasses}
743828

744829
@subsection[#:tag "reference-defining-typeclasses"]{Defining typeclasses and typeclass instances}

hackett-lib/hackett/data/list.rkt

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,55 @@
33
(require hackett/data/maybe
44
hackett/private/prim)
55

6-
(provide (data List) head tail head! tail! take drop filter foldr foldl reverse zip-with sum
7-
repeat cycle! or and any? all? elem? not-elem? delete delete-by)
6+
(provide (data List) head last tail init head! last! tail! init! uncons uncons! null? length take drop
7+
filter foldr foldl reverse zip-with sum repeat cycle! or and any? all? elem? not-elem? delete
8+
delete-by intersperse)
89

910
(defn head : (∀ [a] {(List a) -> (Maybe a)})
1011
[[{x :: _}] (Just x)]
1112
[[Nil ] Nothing])
1213

14+
(defn last : (forall [a] {(List a) -> (Maybe a)})
15+
[[{x :: nil}] (just x)]
16+
[[{_ :: xs} ] (last xs)]
17+
[[_ ] nothing])
18+
1319
(defn tail : (∀ [a] {(List a) -> (Maybe (List a))})
1420
[[{_ :: xs}] (Just xs)]
1521
[[Nil ] Nothing])
1622

23+
(defn init : (forall [a] {(List a) -> (Maybe (List a))})
24+
[[nil] nothing]
25+
[[xs ] (just (init! xs))])
26+
1727
(defn head! : (∀ [a] {(List a) -> a})
1828
[[xs] (from-maybe (error! "head!: empty list") (head xs))])
1929

30+
(defn last! : (forall [a] {(List a) -> a})
31+
[[xs] (from-maybe (error! "last!: empty list") (last xs))])
32+
2033
(defn tail! : (∀ [a] {(List a) -> (List a)})
2134
[[xs] (from-maybe (error! "tail!: empty list") (tail xs))])
2235

36+
(defn init! : (forall [a] {(List a) -> (List a)})
37+
[[{_ :: nil}] nil]
38+
[[{x :: xs} ] {x :: (init! xs)}]
39+
[[nil ] (error! "tail!: empty list")])
40+
41+
(defn uncons : (forall [a] {(List a) -> (Maybe (Tuple a (List a)))})
42+
[[{x :: xs}] (just (tuple x xs))]
43+
[[nil ] nothing])
44+
45+
(defn uncons! : (forall [a] {(List a) -> (Tuple a (List a))})
46+
[[xs] (from-maybe (error! "uncons!: empty list") (uncons xs))])
47+
48+
(defn null? : (forall [a] {(List a) -> Bool})
49+
[[nil] true]
50+
[[_ ] false])
51+
52+
(def length : (forall [a] {(List a) -> Integer})
53+
(foldr (λ [_ acc] {acc + 1}) 0))
54+
2355
(defn take : (∀ [a] {Integer -> (List a) -> (List a)})
2456
[[n {x :: xs}]
2557
(if {n == 0}
@@ -89,3 +121,10 @@
89121
{y :: (delete-by =? x ys)})]
90122
[[_ _ Nil]
91123
Nil])
124+
125+
(defn intersperse : (forall [a] {a -> (List a) -> (List a)})
126+
[[_ nil ] nil]
127+
[[in {x :: xs}] (letrec ([helper
128+
(λ* [[{y :: ys}] {in :: y :: (helper ys)}]
129+
[[nil ] nil])])
130+
{x :: (helper xs)})])

0 commit comments

Comments
 (0)