@@ -15,9 +15,12 @@ import Prelude.Nat
16infixr 7 ::,++
16infixr 7 ::,++
18−%elim data List a
19+%elim data List a =
20− | (::) a (List a)
23+ (::) a (List a)
22-- Name hints for interactive editing
25-- Name hints for interactive editing
23%name List xs, ys, zs, ws
26%name List xs, ys, zs, ws
@@ -26,10 +29,12 @@ infixr 7 ::,++
26-- Syntactic tests
29-- Syntactic tests
27--------------------------------------------------------------------------------
30--------------------------------------------------------------------------------
32+||| Returns `True` iff the argument is empty
29isNil : List a -> Bool
33isNil : List a -> Bool
30isNil [] = True
34isNil [] = True
31isNil (x::xs) = False
35isNil (x::xs) = False
37+||| Returns `True` iff the argument is not empty
33isCons : List a -> Bool
38isCons : List a -> Bool
34isCons [] = False
39isCons [] = False
35isCons (x::xs) = True
40isCons (x::xs) = True
@@ -38,6 +43,9 @@ isCons (x::xs) = True
39--------------------------------------------------------------------------------
44--------------------------------------------------------------------------------
46+||| Compute the length of a list.
48+||| Runs in linear time
41length : List a -> Nat
49length : List a -> Nat
42length [] = 0
50length [] = 0
43length (x::xs) = 1 + length xs
51length (x::xs) = 1 + length xs
@@ -46,49 +54,74 @@ length (x::xs) = 1 + length xs
46-- Indexing into lists
54-- Indexing into lists
47--------------------------------------------------------------------------------
55--------------------------------------------------------------------------------
57+||| Find a particular element of a list.
59+||| @ ok a proof that the index is within bounds
49−index : (n : Nat) -> (l : List a) -> (lt n (length l) = True) -> a
60+index : (n : Nat) -> (l : List a) -> (ok : lt n (length l) = True) -> a
50index Z (x::xs) p = x
61index Z (x::xs) p = x
51index (S n) (x::xs) p = index n xs ?indexTailProof
62index (S n) (x::xs) p = index n xs ?indexTailProof
52index _ [] refl impossible
63index _ [] refl impossible
65+||| Attempt to find a particular element of a list.
67+||| If the provided index is out of bounds, return Nothing.
54index' : (n : Nat) -> (l : List a) -> Maybe a
68index' : (n : Nat) -> (l : List a) -> Maybe a
55index' Z (x::xs) = Just x
69index' Z (x::xs) = Just x
56index' (S n) (x::xs) = index' n xs
70index' (S n) (x::xs) = index' n xs
57index' _ [] = Nothing
71index' _ [] = Nothing
73+||| Get the first element of a non-empty list
74+||| @ ok proof that the list is non-empty
59−head : (l : List a) -> (isCons l = True) -> a
75+head : (l : List a) -> (ok : isCons l = True) -> a
60head [] refl impossible
76head [] refl impossible
61head (x::xs) p = x
77head (x::xs) p = x
79+||| Attempt to get the first element of a list. If the list is empty, return
63head' : (l : List a) -> Maybe a
81head' : (l : List a) -> Maybe a
64head' [] = Nothing
82head' [] = Nothing
65head' (x::xs) = Just x
83head' (x::xs) = Just x
85+||| Get the tail of a non-empty list.
86+||| @ ok proof that the list is non-empty
67−tail : (l : List a) -> (isCons l = True) -> List a
87+tail : (l : List a) -> (ok : isCons l = True) -> List a
68tail [] refl impossible
88tail [] refl impossible
69tail (x::xs) p = xs
89tail (x::xs) p = xs
91+||| Attempt to get the tail of a list.
93+||| If the list is empty, return `Nothing`.
71tail' : (l : List a) -> Maybe (List a)
94tail' : (l : List a) -> Maybe (List a)
72tail' [] = Nothing
95tail' [] = Nothing
73tail' (x::xs) = Just xs
96tail' (x::xs) = Just xs
98+||| Retrieve the last element of a non-empty list.
99+||| @ ok proof that the list is non-empty
75−last : (l : List a) -> (isCons l = True) -> a
100+last : (l : List a) -> (ok : isCons l = True) -> a
76last [] refl impossible
101last [] refl impossible
77last [x] p = x
102last [x] p = x
78last (x::y::ys) p = last (y::ys) refl
103last (x::y::ys) p = last (y::ys) refl
105+||| Attempt to retrieve the last element of a non-empty list.
107+||| If the list is empty, return `Nothing`.
80last' : (l : List a) -> Maybe a
108last' : (l : List a) -> Maybe a
81last' [] = Nothing
109last' [] = Nothing
82−last' (x::xs) =
110+last' (x::xs) =
83 case xs of
111 case xs of
84 [] => Just x
112 [] => Just x
85 y :: ys => last' xs
113 y :: ys => last' xs
115+||| Return all but the last element of a non-empty list.
116+||| @ ok proof that the list is non-empty
87−init : (l : List a) -> (isCons l = True) -> List a
117+init : (l : List a) -> (ok : isCons l = True) -> List a
88init [] refl impossible
118init [] refl impossible
89init [x] p = []
119init [x] p = []
90init (x::y::ys) p = x :: init (y::ys) refl
120init (x::y::ys) p = x :: init (y::ys) refl
122+||| Attempt to Return all but the last element of a list.
124+||| If the list is empty, return `Nothing`.
92init' : (l : List a) -> Maybe (List a)
125init' : (l : List a) -> Maybe (List a)
93init' [] = Nothing
126init' [] = Nothing
94init' (x::xs) =
127init' (x::xs) =
@@ -104,21 +137,39 @@ init' (x::xs) =
104-- Sublists
137-- Sublists
105--------------------------------------------------------------------------------
138--------------------------------------------------------------------------------
140+||| Take the first `n` elements of `xs`
142+||| If there are not enough elements, return the whole list.
143+||| @ n how many elements to take
144+||| @ xs the list to take them from
107−take : Nat -> List a -> List a
145+take : (n : Nat) -> (xs : List a) -> List a
108take Z xs = []
146take Z xs = []
109take (S n) [] = []
147take (S n) [] = []
110take (S n) (x::xs) = x :: take n xs
148take (S n) (x::xs) = x :: take n xs
150+||| Drop the first `n` elements of `xs`
152+||| If there are not enough elements, return the empty list.
153+||| @ n how many elements to drop
154+||| @ xs the list to drop them from
112−drop : Nat -> List a -> List a
155+drop : (n : Nat) -> (xs : List a) -> List a
113drop Z xs = xs
156drop Z xs = xs
114drop (S n) [] = []
157drop (S n) [] = []
115drop (S n) (x::xs) = drop n xs
158drop (S n) (x::xs) = drop n xs
160+||| Take the longest prefix of a list such that all elements satsify some
161+||| Boolean predicate.
163+||| @ p the predicate
117−takeWhile : (a -> Bool) -> List a -> List a
164+takeWhile : (p : a -> Bool) -> List a -> List a
118takeWhile p [] = []
165takeWhile p [] = []
119takeWhile p (x::xs) = if p x then x :: takeWhile p xs else []
166takeWhile p (x::xs) = if p x then x :: takeWhile p xs else []
168+||| Remove the longest prefix of a list such that all removed elements satsify some
169+||| Boolean predicate.
171+||| @ p the predicate
121−dropWhile : (a -> Bool) -> List a -> List a
172+dropWhile : (p : a -> Bool) -> List a -> List a
122dropWhile p [] = []
173dropWhile p [] = []
123dropWhile p (x::xs) = if p x then dropWhile p xs else x::xs
174dropWhile p (x::xs) = if p x then dropWhile p xs else x::xs
@@ -126,7 +177,12 @@ dropWhile p (x::xs) = if p x then dropWhile p xs else x::xs
127--------------------------------------------------------------------------------
178--------------------------------------------------------------------------------
180+||| Simply-typed recursion operator for lists.
182+||| @ nil what to return at the end of the list
183+||| @ cons what to do at each step of recursion
184+||| @ xs the list to recurse over
129−list : a -> (a -> List a -> a) -> List a -> a
185+list : (nil : a) -> (cons : a -> List a -> a) -> (xs : List a) -> a
130list nil cons [] = nil
186list nil cons [] = nil
131list nil cons (x::xs) = cons x xs
187list nil cons (x::xs) = cons x xs
@@ -134,16 +190,23 @@ list nil cons (x::xs) = cons x xs
134-- Building (bigger) lists
190-- Building (bigger) lists
135--------------------------------------------------------------------------------
191--------------------------------------------------------------------------------
137(++) : List a -> List a -> List a
194(++) : List a -> List a -> List a
138−(++) [] right = right
195+(++) [] right = right
139(++) (x::xs) right = x :: (xs ++ right)
196(++) (x::xs) right = x :: (xs ++ right)
198+||| Create an infinite sequence of some item.
200+||| Consider using a `Stream` instead.
142repeat : a -> List a
202repeat : a -> List a
143repeat x = x :: lazy (repeat x)
203repeat x = x :: lazy (repeat x)
205+||| Construct a list with `n` copies of `x`
206+||| @ n how many copies
207+||| @ x the element to replicate
145−replicate : Nat -> a -> List a
208+replicate : (n : Nat) -> (x : a) -> List a
146−replicate Z x = []
209+replicate Z x = []
147replicate (S n) x = x :: replicate n x
210replicate (S n) x = x :: replicate n x
149--------------------------------------------------------------------------------
212--------------------------------------------------------------------------------
@@ -188,15 +251,27 @@ instance Functor List where
188-- Zips and unzips
251-- Zips and unzips
189--------------------------------------------------------------------------------
252--------------------------------------------------------------------------------
254+||| Combine two lists of the same length elementwise using some function.
255+||| @ f the function to combine elements with
256+||| @ l the first list
257+||| @ r the second list
258+||| @ ok a proof that the lengths of the inputs are equal
191zipWith : (f : a -> b -> c) -> (l : List a) -> (r : List b) ->
259zipWith : (f : a -> b -> c) -> (l : List a) -> (r : List b) ->
192− (length l = length r) -> List c
260+ (ok : length l = length r) -> List c
193zipWith f [] (y::ys) refl impossible
261zipWith f [] (y::ys) refl impossible
194zipWith f (x::xs) [] refl impossible
262zipWith f (x::xs) [] refl impossible
195zipWith f [] [] p = []
263zipWith f [] [] p = []
196zipWith f (x::xs) (y::ys) p = f x y :: (zipWith f xs ys ?zipWithTailProof)
264zipWith f (x::xs) (y::ys) p = f x y :: (zipWith f xs ys ?zipWithTailProof)
266+||| Combine three lists of the same length elementwise using some function.
267+||| @ f the function to combine elements with
268+||| @ x the first list
269+||| @ y the second list
270+||| @ z the third list
271+||| @ ok a proof that the lengths of the first two inputs are equal
272+||| @ ok' a proof that the lengths of the second and third inputs are equal
198zipWith3 : (f : a -> b -> c -> d) -> (x : List a) -> (y : List b) ->
273zipWith3 : (f : a -> b -> c -> d) -> (x : List a) -> (y : List b) ->
199− (z : List c) -> (length x = length y) -> (length y = length z) -> List d
274+ (z : List c) -> (ok : length x = length y) -> (ok' : length y = length z) -> List d
200zipWith3 f _ [] (z::zs) p refl impossible
275zipWith3 f _ [] (z::zs) p refl impossible
201zipWith3 f _ (y::ys) [] p refl impossible
276zipWith3 f _ (y::ys) [] p refl impossible
202zipWith3 f [] (y::ys) _ refl q impossible
277zipWith3 f [] (y::ys) _ refl q impossible
@@ -205,18 +280,22 @@ zipWith3 f [] [] [] p q = []
205zipWith3 f (x::xs) (y::ys) (z::zs) p q =
280zipWith3 f (x::xs) (y::ys) (z::zs) p q =
206 f x y z :: (zipWith3 f xs ys zs ?zipWith3TailProof ?zipWith3TailProof')
281 f x y z :: (zipWith3 f xs ys zs ?zipWith3TailProof ?zipWith3TailProof')
283+||| Combine two lists elementwise into pairs
208zip : (l : List a) -> (r : List b) -> (length l = length r) -> List (a, b)
284zip : (l : List a) -> (r : List b) -> (length l = length r) -> List (a, b)
209zip = zipWith (\x => \y => (x, y))
285zip = zipWith (\x => \y => (x, y))
287+||| Combine three lists elementwise into tuples
211zip3 : (x : List a) -> (y : List b) -> (z : List c) -> (length x = length y) ->
288zip3 : (x : List a) -> (y : List b) -> (z : List c) -> (length x = length y) ->
212 (length y = length z) -> List (a, b, c)
289 (length y = length z) -> List (a, b, c)
213zip3 = zipWith3 (\x => \y => \z => (x, y, z))
290zip3 = zipWith3 (\x => \y => \z => (x, y, z))
292+||| Split a list of pairs into two lists
215unzip : List (a, b) -> (List a, List b)
293unzip : List (a, b) -> (List a, List b)
216unzip [] = ([], [])
294unzip [] = ([], [])
217unzip ((l, r)::xs) with (unzip xs)
295unzip ((l, r)::xs) with (unzip xs)
218 | (lefts, rights) = (l::lefts, r::rights)
296 | (lefts, rights) = (l::lefts, r::rights)
298+||| Split a list of triples into three lists
220unzip3 : List (a, b, c) -> (List a, List b, List c)
299unzip3 : List (a, b, c) -> (List a, List b, List c)
221unzip3 [] = ([], [], [])
300unzip3 [] = ([], [], [])
222unzip3 ((l, c, r)::xs) with (unzip3 xs)
301unzip3 ((l, c, r)::xs) with (unzip3 xs)
@@ -226,6 +305,8 @@ unzip3 ((l, c, r)::xs) with (unzip3 xs)
227--------------------------------------------------------------------------------
306--------------------------------------------------------------------------------
308+||| Apply a partial function to the elements of a list, keeping the ones at which
229mapMaybe : (a -> Maybe b) -> List a -> List b
310mapMaybe : (a -> Maybe b) -> List a -> List b
230mapMaybe f [] = []
311mapMaybe f [] = []
231mapMaybe f (x::xs) =
312mapMaybe f (x::xs) =
@@ -237,6 +318,7 @@ mapMaybe f (x::xs) =
238--------------------------------------------------------------------------------
319--------------------------------------------------------------------------------
321+||| A tail recursive right fold on Lists.
240total foldrImpl : (t -> acc -> acc) -> acc -> (acc -> acc) -> List t -> acc
322total foldrImpl : (t -> acc -> acc) -> acc -> (acc -> acc) -> List t -> acc
241foldrImpl f e go [] = go e
323foldrImpl f e go [] = go e
242foldrImpl f e go (x::xs) = foldrImpl f e (go . (f x)) xs
324foldrImpl f e go (x::xs) = foldrImpl f e (go . (f x)) xs
@@ -248,6 +330,7 @@ instance Foldable List where
248-- Special folds
330-- Special folds
249--------------------------------------------------------------------------------
331--------------------------------------------------------------------------------
333+||| Convert any Foldable structure to a list.
251toList : Foldable t => t a -> List a
334toList : Foldable t => t a -> List a
252toList = foldr (::) []
335toList = foldr (::) []
@@ -255,6 +338,7 @@ toList = foldr (::) []
255-- Transformations
338-- Transformations
256--------------------------------------------------------------------------------
339--------------------------------------------------------------------------------
341+||| Return the elements of a list in reverse order.
258reverse : List a -> List a
342reverse : List a -> List a
259reverse = reverse' []
343reverse = reverse' []
@@ -262,6 +346,7 @@ reverse = reverse' []
262 reverse' acc [] = acc
346 reverse' acc [] = acc
263 reverse' acc (x::xs) = reverse' (x::acc) xs
347 reverse' acc (x::xs) = reverse' (x::acc) xs
349+||| Insert some separator between the elements of a list.
265intersperse : a -> List a -> List a
350intersperse : a -> List a -> List a
266intersperse sep [] = []
351intersperse sep [] = []
267intersperse sep (x::xs) = x :: intersperse' sep xs
352intersperse sep (x::xs) = x :: intersperse' sep xs
@@ -275,13 +360,13 @@ intercalate sep l = concat $ intersperse sep l
276||| Transposes rows and columns of a list of lists.
361||| Transposes rows and columns of a list of lists.
278−||| > transpose [[1, 2], [3, 4]] = [[1, 3], [2, 4]]
363+||| > transpose [[1, 2], [3, 4]] = [[1, 3], [2, 4]]
280||| This also works for non square scenarios, thus
365||| This also works for non square scenarios, thus
281||| involution does not always hold:
366||| involution does not always hold:
283−||| > transpose [[], [1, 2]] = [[1], [2]]
368+||| > transpose [[], [1, 2]] = [[1], [2]]
284−||| > transpose (transpose [[], [1, 2]]) = [[1, 2]]
369+||| > transpose (transpose [[], [1, 2]]) = [[1, 2]]
286||| TODO: Solution which satisfies the totality checker?
371||| TODO: Solution which satisfies the totality checker?
287%assert_total
372%assert_total
@@ -294,6 +379,7 @@ transpose ((x::xs) :: xss) = (x :: (mapMaybe head' xss)) :: (transpose (xs :: (m
294-- Membership tests
379-- Membership tests
295--------------------------------------------------------------------------------
380--------------------------------------------------------------------------------
382+||| Check if something is a member of a list using a custom comparison.
297elemBy : (a -> a -> Bool) -> a -> List a -> Bool
383elemBy : (a -> a -> Bool) -> a -> List a -> Bool
298elemBy p e [] = False
384elemBy p e [] = False
299elemBy p e (x::xs) =
385elemBy p e (x::xs) =
@@ -302,9 +388,11 @@ elemBy p e (x::xs) =
303 elemBy p e xs
389 elemBy p e xs
391+||| Check if something is a member of a list using the default Boolean equality.
305elem : Eq a => a -> List a -> Bool
392elem : Eq a => a -> List a -> Bool
306elem = elemBy (==)
393elem = elemBy (==)
395+||| Find associated information in a list using a custom comparison.
308lookupBy : (a -> a -> Bool) -> a -> List (a, b) -> Maybe b
396lookupBy : (a -> a -> Bool) -> a -> List (a, b) -> Maybe b
309lookupBy p e [] = Nothing
397lookupBy p e [] = Nothing
310lookupBy p e (x::xs) =
398lookupBy p e (x::xs) =
@@ -314,9 +402,12 @@ lookupBy p e (x::xs) =
315 lookupBy p e xs
403 lookupBy p e xs
405+||| Find associated information in a list using Boolean equality.
317lookup : Eq a => a -> List (a, b) -> Maybe b
406lookup : Eq a => a -> List (a, b) -> Maybe b
318lookup = lookupBy (==)
407lookup = lookupBy (==)
409+||| Check if any elements of the first list are found in the second, using
410+||| a custom comparison.
320hasAnyBy : (a -> a -> Bool) -> List a -> List a -> Bool
411hasAnyBy : (a -> a -> Bool) -> List a -> List a -> Bool
321hasAnyBy p elems [] = False
412hasAnyBy p elems [] = False
322hasAnyBy p elems (x::xs) =
413hasAnyBy p elems (x::xs) =
@@ -325,6 +416,8 @@ hasAnyBy p elems (x::xs) =
326 hasAnyBy p elems xs
417 hasAnyBy p elems xs
419+||| Check if any elements of the first list are found in the second, using
420+||| Boolean equality.
328hasAny : Eq a => List a -> List a -> Bool
421hasAny : Eq a => List a -> List a -> Bool
329hasAny = hasAnyBy (==)
422hasAny = hasAnyBy (==)
@@ -332,6 +425,7 @@ hasAny = hasAnyBy (==)
332-- Searching with a predicate
425-- Searching with a predicate
333--------------------------------------------------------------------------------
426--------------------------------------------------------------------------------
428+||| Find the first element of a list that satisfies a predicate, or `Nothing` if none do.
335find : (a -> Bool) -> List a -> Maybe a
429find : (a -> Bool) -> List a -> Maybe a
336find p [] = Nothing
430find p [] = Nothing
337find p (x::xs) =
431find p (x::xs) =
@@ -340,6 +434,8 @@ find p (x::xs) =
341 find p xs
435 find p xs
437+||| Find the index of the first element of a list that satisfies a predicate, or
438+||| `Nothing` if none do.
343findIndex : (a -> Bool) -> List a -> Maybe Nat
439findIndex : (a -> Bool) -> List a -> Maybe Nat
344findIndex = findIndex' Z
440findIndex = findIndex' Z
@@ -351,6 +447,7 @@ findIndex = findIndex' Z
352 findIndex' (S cnt) p xs
448 findIndex' (S cnt) p xs
450+||| Find the indices of all elements that satisfy some predicate.
354findIndices : (a -> Bool) -> List a -> List Nat
451findIndices : (a -> Bool) -> List a -> List Nat
355findIndices = findIndices' Z
452findIndices = findIndices' Z
@@ -420,6 +517,8 @@ union = unionBy (==)
420-- Splitting and breaking lists
517-- Splitting and breaking lists
421--------------------------------------------------------------------------------
518--------------------------------------------------------------------------------
520+||| Given a list and a predicate, returns a pair consisting of the longest
521+||| prefix of the list that satisfies a predicate and the rest of the list.
423span : (a -> Bool) -> List a -> (List a, List a)
522span : (a -> Bool) -> List a -> (List a, List a)
424span p [] = ([], [])
523span p [] = ([], [])
425span p (x::xs) =
524span p (x::xs) =
@@ -528,6 +627,7 @@ sort xs = let (x, y) = split xs in
528-- Conversions
627-- Conversions
529--------------------------------------------------------------------------------
628--------------------------------------------------------------------------------
630+||| Either return the head of a list, or `Nothing` if it is empty.
531listToMaybe : List a -> Maybe a
631listToMaybe : List a -> Maybe a
532listToMaybe [] = Nothing
632listToMaybe [] = Nothing
533listToMaybe (x::xs) = Just x
633listToMaybe (x::xs) = Just x
@@ -547,7 +647,7 @@ catMaybes (x::xs) =
547-- Properties
647-- Properties
548--------------------------------------------------------------------------------
648--------------------------------------------------------------------------------
550−-- append
650+||| The empty list is a right identity for append.
551appendNilRightNeutral : (l : List a) ->
651appendNilRightNeutral : (l : List a) ->
552 l ++ [] = l
652 l ++ [] = l
553appendNilRightNeutral [] = refl
653appendNilRightNeutral [] = refl
@@ -555,6 +655,7 @@ appendNilRightNeutral (x::xs) =
555 let inductiveHypothesis = appendNilRightNeutral xs in
655 let inductiveHypothesis = appendNilRightNeutral xs in
556 ?appendNilRightNeutralStepCase
656 ?appendNilRightNeutralStepCase
658+||| Appending lists is associative.
558appendAssociative : (l : List a) -> (c : List a) -> (r : List a) ->
659appendAssociative : (l : List a) -> (c : List a) -> (r : List a) ->
559 l ++ (c ++ r) = (l ++ c) ++ r
660 l ++ (c ++ r) = (l ++ c) ++ r
560appendAssociative [] c r = refl
661appendAssociative [] c r = refl
@@ -562,7 +663,8 @@ appendAssociative (x::xs) c r =
562 let inductiveHypothesis = appendAssociative xs c r in
663 let inductiveHypothesis = appendAssociative xs c r in
563 ?appendAssociativeStepCase
664 ?appendAssociativeStepCase
565−-- length
666+||| The length of two lists that are appended is the sum of the lengths
667+||| of the input lists.
566lengthAppend : (left : List a) -> (right : List a) ->
668lengthAppend : (left : List a) -> (right : List a) ->
567 length (left ++ right) = length left + length right
669 length (left ++ right) = length left + length right
568lengthAppend [] right = refl
670lengthAppend [] right = refl
@@ -570,7 +672,7 @@ lengthAppend (x::xs) right =
570 let inductiveHypothesis = lengthAppend xs right in
672 let inductiveHypothesis = lengthAppend xs right in
571 ?lengthAppendStepCase
673 ?lengthAppendStepCase
573−-- map
675+||| Mapping a function over a list doesn't change its length.
574mapPreservesLength : (f : a -> b) -> (l : List a) ->
676mapPreservesLength : (f : a -> b) -> (l : List a) ->
575 length (map f l) = length l
677 length (map f l) = length l
576mapPreservesLength f [] = refl
678mapPreservesLength f [] = refl
@@ -578,6 +680,8 @@ mapPreservesLength f (x::xs) =
578 let inductiveHypothesis = mapPreservesLength f xs in
680 let inductiveHypothesis = mapPreservesLength f xs in
579 ?mapPreservesLengthStepCase
681 ?mapPreservesLengthStepCase
683+||| Mapping a function over two lists and appending them is equivalent
684+||| to appending them and then mapping the function.
581mapDistributesOverAppend : (f : a -> b) -> (l : List a) -> (r : List a) ->
685mapDistributesOverAppend : (f : a -> b) -> (l : List a) -> (r : List a) ->
582 map f (l ++ r) = map f l ++ map f r
686 map f (l ++ r) = map f l ++ map f r
583mapDistributesOverAppend f [] r = refl
687mapDistributesOverAppend f [] r = refl
@@ -585,6 +689,7 @@ mapDistributesOverAppend f (x::xs) r =
585 let inductiveHypothesis = mapDistributesOverAppend f xs r in
689 let inductiveHypothesis = mapDistributesOverAppend f xs r in
586 ?mapDistributesOverAppendStepCase
690 ?mapDistributesOverAppendStepCase
692+||| Mapping two functions is the same as mapping their composition.
588mapFusion : (f : b -> c) -> (g : a -> b) -> (l : List a) ->
693mapFusion : (f : b -> c) -> (g : a -> b) -> (l : List a) ->
589 map f (map g l) = map (f . g) l
694 map f (map g l) = map (f . g) l
590mapFusion f g [] = refl
695mapFusion f g [] = refl
@@ -592,7 +697,7 @@ mapFusion f g (x::xs) =
592 let inductiveHypothesis = mapFusion f g xs in
697 let inductiveHypothesis = mapFusion f g xs in
593 ?mapFusionStepCase
698 ?mapFusionStepCase
595−-- hasAny
700+||| No list contains an element of the empty list by any predicate.
596hasAnyByNilFalse : (p : a -> a -> Bool) -> (l : List a) ->
701hasAnyByNilFalse : (p : a -> a -> Bool) -> (l : List a) ->
597 hasAnyBy p [] l = False
702 hasAnyBy p [] l = False
598hasAnyByNilFalse p [] = refl
703hasAnyByNilFalse p [] = refl
@@ -600,6 +705,7 @@ hasAnyByNilFalse p (x::xs) =
600 let inductiveHypothesis = hasAnyByNilFalse p xs in
705 let inductiveHypothesis = hasAnyByNilFalse p xs in
601 ?hasAnyByNilFalseStepCase
706 ?hasAnyByNilFalseStepCase
708+||| No list contains an element of the empty list.
603hasAnyNilFalse : Eq a => (l : List a) -> hasAny [] l = False
709hasAnyNilFalse : Eq a => (l : List a) -> hasAny [] l = False
604hasAnyNilFalse l = ?hasAnyNilFalseBody
710hasAnyNilFalse l = ?hasAnyNilFalseBody