@@ -15,8 +15,8 @@ public enum ArrayMatcher<A> {
1515
1616/// Destructures a list into its constituent parts.
1717///
18- /// If the given list is empty, this function returns .Empty . If the list is non-empty, this
19- /// function returns .Cons(hd, tl )
18+ /// If the given list is empty, this function returns .Nil . If the list is non-empty, this
19+ /// function returns .Cons(head, tail )
2020public func match< T> ( l : [ T ] ) -> ArrayMatcher < T > {
2121 if l. count == 0 {
2222 return . Nil
@@ -48,6 +48,32 @@ public func tail<A>(l : [A]) -> Optional<[A]> {
4848 }
4949}
5050
51+ /// Takes, at most, a specified number of elements from a list and returns that sublist.
52+ ///
53+ /// take(3, from: [1,2]) == [1,2]
54+ /// take(-1, from: [1,2]) == []
55+ /// take(0, from: [1,2]) == []
56+ public func take< A> ( n : Int , from list : [ A ] ) -> [ A ] {
57+ if n <= 0 {
58+ return [ ]
59+ }
60+
61+ return Array ( list [ 0 ..< min ( n, list. count) ] )
62+ }
63+
64+ /// Drops, at most, a specified number of elements from a list and returns that sublist.
65+ ///
66+ /// drop(3, from: [1,2]) == []
67+ /// drop(-1, from: [1,2]) == [1,2]
68+ /// drop(0, from: [1,2]) == [1,2]
69+ public func drop< A> ( n : Int , from list : [ A ] ) -> [ A ] {
70+ if n <= 0 {
71+ return list
72+ }
73+
74+ return Array ( list [ min ( n, list. count) ..< list. count] )
75+ }
76+
5177/// Adds an element to the front of a list.
5278public func cons< T> ( lhs : T , var rhs : [ T ] ) -> [ T ] {
5379 rhs. insert ( lhs, atIndex: 0 )
@@ -121,15 +147,8 @@ public func find<T>(list : [T], f : (T -> Bool)) -> T? {
121147/// splitAt(3, [1,2,3]) == ([1,2,3],[])
122148/// splitAt(4, [1,2,3]) == ([1,2,3],[])
123149/// splitAt(0, [1,2,3]) == ([],[1,2,3])
124- public func splitAt< T> ( index : Int , list : [ T ] ) -> ( [ T ] , [ T ] ) {
125- switch index {
126- case 0 ..< list. count:
127- return ( Array ( list [ 0 ..< index] ) , Array ( list [ index..< list. count] ) )
128- case list. count... Int . max:
129- return ( list, [ T] ( ) )
130- default :
131- return ( [ T] ( ) , [ T] ( ) )
132- }
150+ public func splitAt< T> ( n : Int , list : [ T ] ) -> ( [ T ] , [ T ] ) {
151+ return ( take ( n, from: list) , drop ( n, from: list) )
133152}
134153
135154/// Takes a separator and a list and intersperses that element throughout the list.
@@ -151,7 +170,7 @@ public func intersperse<T>(item : T, list : [T]) -> [T] {
151170 return list
152171 } else {
153172 var array = Array ( [ list [ 0 ] ] )
154- array += prependAll ( item, Array ( list [ 1 ..< list . count ] ) )
173+ array += prependAll ( item, tail ( list) ! )
155174 return Array ( array)
156175 }
157176}
@@ -275,32 +294,28 @@ public func intercalate<A>(list : [A], nested : [[A]]) -> [A] {
275294///
276295/// span(list, p) == (takeWhile(list, p), dropWhile(list, p))
277296public func span< A> ( list : [ A ] , p : ( A -> Bool ) ) -> ( [ A ] , [ A ] ) {
278- switch list. count {
279- case 0 :
280- return ( list, list)
281- case 1 ... list. count where p ( list. first!) :
282- let first = list. first!
283- let ( ys, zs) = span ( Array ( list [ 1 ..< list. count] ) , p)
284- let f = concat ( lhs: [ first] ) ( rhs: ys)
285- return ( f, zs)
286- default :
297+ switch match ( list) {
298+ case . Nil:
299+ return ( [ ] , [ ] )
300+ case . Cons( let x, let xs) :
301+ if p ( x) {
302+ let ( ys, zs) = span ( xs, p)
303+ return ( cons ( x, ys) , zs)
304+ }
287305 return ( [ ] , list)
288306 }
289307}
290308
291309/// Takes a list and groups its arguments into sublists of duplicate elements found next to each
292310/// other according to an equality predicate.
293- public func groupBy< A> ( list : [ A ] , p : ( A -> A -> Bool ) ) -> [ [ A ] ] {
294- switch list. count {
295- case 0 :
296- return [ ]
297- case 1 ... list. count:
298- let first = list. first!
299- let ( ys, zs) = span ( Array ( list [ 1 ..< list. count] ) , p ( first) )
300- let x = [ concat ( lhs: [ first] ) ( rhs: ys) ]
301- return concat ( lhs: x) ( rhs: groupBy ( zs, p) )
302- default :
311+ public func groupBy< A> ( list : [ A ] , p : A -> A -> Bool ) -> [ [ A ] ] {
312+ switch match ( list) {
313+ case . Nil:
303314 return [ ]
315+ case . Cons( let x, let xs) :
316+ let ( ys, zs) = span ( xs, p ( x) )
317+ let l = cons ( x, ys)
318+ return cons ( l, groupBy ( zs, p) )
304319 }
305320}
306321
@@ -309,40 +324,42 @@ public func groupBy<A>(list : [A], p : (A -> A -> Bool)) -> [[A]] {
309324/// other.
310325///
311326/// group([0, 1, 1, 2, 3, 3, 4, 5, 6, 7, 7]) == [[0], [1, 1], [2], [3, 3], [4], [5], [6], [7, 7]]
312- public func group< A: Equatable > ( list : [ A ] ) -> [ [ A ] ] {
327+ public func group< A : Equatable > ( list : [ A ] ) -> [ [ A ] ] {
313328 return groupBy ( list, { a in { b in a == b } } )
314329}
315330
316331/// Returns a list of the first elements that do not satisfy a predicate until that predicate
317332/// returns false.
318333///
319- /// dropWhile([1, 2, 3, 4, 5, 1, 2, 3]){ <3 } == [3,4,5,1,2,3]
320- /// dropWhile([1, 2, 3]){ <9 } == []
321- /// dropWhile([1, 2, 3]){ <0 } == [1,2,3]
334+ /// dropWhile([1, 2, 3, 4, 5, 1, 2, 3], <3) == [3,4,5,1,2,3]
335+ /// dropWhile([1, 2, 3], <9) == []
336+ /// dropWhile([1, 2, 3], <0) == [1,2,3]
322337public func dropWhile< A> ( list : [ A ] , p : A -> Bool ) -> [ A ] {
323- switch list. count {
324- case 0 :
325- return list
326- case 1 ... list. count where p ( list. first!) :
327- return dropWhile ( Array ( list [ 1 ..< list. count] ) , p)
328- default :
338+ switch match ( list) {
339+ case . Nil:
340+ return [ ]
341+ case . Cons( let x, let xs) :
342+ if p ( x) {
343+ return dropWhile ( xs, p)
344+ }
329345 return list
330346 }
331347}
332348
333349/// Returns a list of the first elements that satisfy a predicate until that predicate returns
334350/// false.
335351///
336- /// takeWhile([1, 2, 3, 4, 1, 2, 3, 4]){ <3 } == [1, 2]
337- /// takeWhile([1,2,3]){ <9 } == [1, 2, 3]
338- /// takeWhile([1,2,3]){ <0 } == []
339- public func takeWhile< A> ( list: [ A ] , p: A -> Bool ) -> [ A ] {
340- switch list. count {
341- case 0 :
342- return list
343- case 1 ... list. count where p ( list. first!) :
344- return concat ( lhs: [ list. first!] ) ( rhs: takeWhile ( Array ( list [ 1 ..< list. count] ) , p) )
345- default :
352+ /// takeWhile([1, 2, 3, 4, 1, 2, 3, 4], <3) == [1, 2]
353+ /// takeWhile([1,2,3], <9) == [1, 2, 3]
354+ /// takeWhile([1,2,3], <0) == []
355+ public func takeWhile< A> ( list : [ A ] , p : A -> Bool ) -> [ A ] {
356+ switch match ( list) {
357+ case . Nil:
358+ return [ ]
359+ case . Cons( let x, let xs) :
360+ if p ( x) {
361+ return cons ( x, takeWhile ( xs, p) )
362+ }
346363 return [ ]
347364 }
348365}
0 commit comments