7
7
> % hide Prelude . Basics . fst
8
8
> % hide Prelude . Basics . snd
9
9
> % hide Prelude . Nat . pred
10
+ > % hide Prelude . List . (++ )
10
11
11
12
> % access public export
12
13
> % default total
@@ -124,27 +125,20 @@ and another list."
124
125
125
126
> data NatList : Type where
126
127
> Nil : NatList
127
- > Cons : Nat -> NatList -> NatList
128
+ > (::) : Nat -> NatList -> NatList
128
129
129
130
For example, here is a three-element list:
130
131
131
132
> mylist : NatList
132
- > mylist = Cons 1 (Cons 2 (Cons 3 Nil))
133
+ > mylist = (::) 1 ((::) 2 ((::) 3 Nil))
134
+
135
+ \t odo[inline]{Edit the section - Idris's list sugar automatically works for
136
+ anything with constructors \idr{Nil} and \idr{(::)}}
133
137
134
138
As with pairs, it is more convenient to write lists in familiar programming
135
139
notation. The following declarations allow us to use \idr{::} as an infix Cons
136
140
operator and square brackets as an " outfix" notation for constructing lists.
137
141
138
- > syntax [x] " :: " [l] = Cons x l
139
- > syntax " [ ]" = Nil
140
-
141
- \t odo[inline]{Seems it's impossible to make an Idris \idr{syntax} to overload
142
- the list notation. Edit the section.}
143
-
144
- ```coq
145
- Notation " [ x ; .. ; y ]" := ( cons x .. ( cons y nil ) ..).
146
- ```
147
-
148
142
It is not necessary to understand the details of these declarations, but in case
149
143
you are interested, here is roughly what's going on. The right associativity
150
144
annotation tells Coq how to parenthesize expressions involving several uses of
@@ -155,9 +149,10 @@ thing:
155
149
> mylist1 = 1 :: (2 :: (3 :: Nil))
156
150
157
151
> mylist2 : NatList
158
- > mylist2 = 1::2::3::Nil
152
+ > mylist2 = 1::2::3::[]
159
153
160
- Definition mylist3 := [1;2;3].
154
+ > mylist3 : NatList
155
+ > mylist3 = [1,2,3]
161
156
162
157
The at level 60 part tells Coq how to parenthesize expressions that involve both
163
158
:: and some other infix operator. For example, since we defined + as infix
@@ -190,7 +185,7 @@ A number of functions are useful for manipulating lists. For example, the
190
185
list of length \idr{count} where every element is \idr{n}.
191
186
192
187
> repeat : (n, count : Nat) -> NatList
193
- > repeat n Z = Nil
188
+ > repeat n Z = []
194
189
> repeat n (S k) = n :: repeat n k
195
190
196
191
@@ -199,7 +194,7 @@ list of length \idr{count} where every element is \idr{n}.
199
194
The \idr{length} function calculates the length of a list.
200
195
201
196
> length : (l : NatList) -> Nat
202
- > length Nil = Z
197
+ > length [] = Z
203
198
> length (h :: t) = S (length t)
204
199
205
200
@@ -208,21 +203,24 @@ The \idr{length} function calculates the length of a list.
208
203
The \idr{app} function concatenates (appends) two lists.
209
204
210
205
> app : (l1, l2 : NatList) -> NatList
211
- > app Nil l2 = l2
206
+ > app [] l2 = l2
212
207
> app (h :: t) l2 = h :: app t l2
213
208
214
209
Actually, \idr{app} will be used a lot in some parts of what follows, so it is
215
210
convenient to have an infix operator for it.
216
211
217
- > syntax [x] " ++ " [y] = app x y
212
+ > infixr 7 ++
213
+
214
+ > (++) : (x, y : NatList) -> NatList
215
+ > (++) = app
218
216
219
- > test_app1 : ((1::2::3::[]) ++ (4::5::[])) = (1::2::3::4::5::[])
217
+ > test_app1 : [1,2,3] ++ [4,5,6] = [1,2,3,4,5,6]
220
218
> test_app1 = Refl
221
219
222
- > test_app2 : ( [] ++ (4::5::[])) = (4::5::[])
220
+ > test_app2 : [] ++ [4,5] = [4,5]
223
221
> test_app2 = Refl
224
222
225
- > test_app3 : ((1::2::3::[]) ++ []) = (1::2::3::[])
223
+ > test_app3 : [1,2,3] ++ [] = [1,2,3]
226
224
> test_app3 = Refl
227
225
228
226
@@ -234,20 +232,20 @@ everything but the first element (the "tail"). Of course, the empty list has no
234
232
first element, so we must pass a default value to be returned in that case.
235
233
236
234
> hd : (default : Nat) -> (l : NatList) -> Nat
237
- > hd default Nil = default
235
+ > hd default [] = default
238
236
> hd default (h :: t) = h
239
237
240
238
> tl : (l : NatList) -> NatList
241
- > tl Nil = Nil
239
+ > tl [] = []
242
240
> tl (h :: t) = t
243
241
244
- > test_hd1 : hd 0 (1::2::3::[]) = 1
242
+ > test_hd1 : hd 0 [1,2,3] = 1
245
243
> test_hd1 = Refl
246
244
247
245
> test_hd2 : hd 0 [] = 0
248
246
> test_hd2 = Refl
249
247
250
- > test_tl : tl (1::2::3::[]) = (2::3::[])
248
+ > test_tl : tl [1,2,3] = [2,3]
251
249
> test_tl = Refl
252
250
253
251
@@ -263,19 +261,19 @@ functions should do.
263
261
> nonzeros : (l : NatList) -> NatList
264
262
> nonzeros l = ?nonzeros_rhs
265
263
266
- > test_nonzeros : nonzeros (0::1::0::2::3::0::0::[]) = (1::2::3::[])
264
+ > test_nonzeros : nonzeros [0,1,0,2,3,0,0] = [1,2,3]
267
265
> test_nonzeros = ?test_nonzeros_rhs
268
266
269
267
> oddmembers : (l : NatList) -> NatList
270
268
> oddmembers l = ?oddmembers_rhs
271
269
272
- > test_oddmembers : oddmembers (0::1::0::2::3::0::0::[]) = (1::3::[])
270
+ > test_oddmembers : oddmembers [0,1,0,2,3,0,0] = [1,3]
273
271
> test_oddmembers = ?test_oddmembers_rhs
274
272
275
273
> countoddmembers : (l : NatList) -> Nat
276
274
> countoddmembers l = ?countoddmembers_rhs
277
275
278
- > test_countoddmembers1 : countoddmembers (1::0::3::1::4::5::[]) = 4
276
+ > test_countoddmembers1 : countoddmembers [1,0,3,1,4,5] = 4
279
277
> test_countoddmembers1 = ?test_countoddmembers1_rhs
280
278
281
279
$\square$
@@ -296,17 +294,17 @@ solution requires defining a new kind of pairs, but this is not the only way.)
296
294
> alternate : (l1, l2 : NatList) -> NatList
297
295
> alternate l1 l2 = ?alternate_rhs
298
296
299
- > test_alternate1 : alternate (1::2::3::[]) (4::5::6::[]) =
300
- > (1::4::2::5::3::6::[])
297
+ > test_alternate1 : alternate [1,2,3] [4,5,6] =
298
+ > [1,4,2,5,3,6]
301
299
> test_alternate1 = ?test_alternate1_rhs
302
300
303
- > test_alternate2 : alternate (1::[]) (4::5::6::[]) = (1::4::5::6::[])
301
+ > test_alternate2 : alternate [1] [4,5,6] = [1,4,5,6]
304
302
> test_alternate2 = ?test_alternate2_rhs
305
303
306
- > test_alternate3 : alternate (1::2::3::[]) (4::[]) = (1::4::2::3::[])
304
+ > test_alternate3 : alternate [1,2,3] [4] = [1,4,2,3]
307
305
> test_alternate3 = ?test_alternate3_rhs
308
306
309
- > test_alternate4 : alternate [] (20::30::[]) = (20::30::[])
307
+ > test_alternate4 : alternate [] [20,30] = [20,30]
310
308
> test_alternate4 = ?test_alternate4_rhs
311
309
312
310
$\square$
@@ -332,10 +330,10 @@ Complete the following definitions for the functions \idr{count}, \idr{sum},
332
330
333
331
All these proofs can be done just by \idr{Refl}.
334
332
335
- > test_count1 : count 1 (1::2::3::1::4::1::[]) = 3
333
+ > test_count1 : count 1 [1,2,3,1,4,1] = 3
336
334
> test_count1 = ?test_count1_rhs
337
335
338
- > test_count2 : count 6 (1::2::3::1::4::1::[]) = 0
336
+ > test_count2 : count 6 [1,2,3,1,4,1] = 0
339
337
> test_count2 = ?test_count2_rhs
340
338
341
339
Multiset \idr{sum} is similar to set \idr{union}: \idr{sum a b} contains all the
@@ -355,25 +353,25 @@ functions that have already been defined.
355
353
> sum : Bag -> Bag -> Bag
356
354
> sum x y = ?sum_rhs
357
355
358
- > test_sum1 : count 1 (sum (1::2::3::[]) (1::4::1::[]) ) = 3
356
+ > test_sum1 : count 1 (sum [1,2,3] [1,4,1] ) = 3
359
357
> test_sum1 = ?test_sum1_rhs
360
358
361
359
> add : (v : Nat) -> (s : Bag) -> Bag
362
360
> add v s = ?add_rhs
363
361
364
- > test_add1 : count 1 (add 1 (1::4::1::[]) ) = 3
362
+ > test_add1 : count 1 (add 1 [1,4,1] ) = 3
365
363
> test_add1 = ?test_add1_rhs
366
364
367
- > test_add2 : count 5 (add 1 (1::4::1::[]) ) = 0
365
+ > test_add2 : count 5 (add 1 [1,4,1] ) = 0
368
366
> test_add2 = ?test_add2_rhs
369
367
370
368
> member : (v : Nat) -> (s : Bag) -> Bool
371
369
> member v s = ?member_rhs
372
370
373
- > test_member1 : member 1 (1::4::1::[]) = True
371
+ > test_member1 : member 1 [1,4,1] = True
374
372
> test_member1 = ?test_member1_rhs
375
373
376
- > test_member2 : member 2 (1::4::1::[]) = False
374
+ > test_member2 : member 2 [1,4,1] = False
377
375
> test_member2 = ?test_member2_rhs
378
376
379
377
$\square$
@@ -389,41 +387,41 @@ should return the same bag unchanged.
389
387
> remove_one : (v : Nat) -> (s : Bag) -> Bag
390
388
> remove_one v s = ?remove_one_rhs
391
389
392
- > test_remove_one1 : count 5 (remove_one 5 (2::1::5::4::1::[]) ) = 0
390
+ > test_remove_one1 : count 5 (remove_one 5 [2,1,5,4,1] ) = 0
393
391
> test_remove_one1 = ?test_remove_one1_rhs
394
392
395
- > test_remove_one2 : count 5 (remove_one 5 (2::1::4::1::[]) ) = 0
393
+ > test_remove_one2 : count 5 (remove_one 5 [2,1,4,1] ) = 0
396
394
> test_remove_one2 = ?test_remove_one2_rhs
397
395
398
- > test_remove_one3 : count 4 (remove_one 5 (2::1::5::4::1::4::[]) ) = 2
396
+ > test_remove_one3 : count 4 (remove_one 5 [2,1,5,4,1,4] ) = 2
399
397
> test_remove_one3 = ?test_remove_one3_rhs
400
398
401
- > test_remove_one4 : count 5 (remove_one 5 (2::1::5::4::5::1::4::[]) ) = 1
399
+ > test_remove_one4 : count 5 (remove_one 5 [2,1,5,4,5,1,4] ) = 1
402
400
> test_remove_one4 = ?test_remove_one4_rhs
403
401
404
402
> remove_all : (v : Nat) -> (s : Bag) -> Bag
405
403
> remove_all v s = ?remove_all_rhs
406
404
407
- > test_remove_all1 : count 5 (remove_all 5 (2::1::5::4::1::[]) ) = 0
405
+ > test_remove_all1 : count 5 (remove_all 5 [2,1,5,4,1] ) = 0
408
406
> test_remove_all1 = ?test_remove_all1_rhs
409
407
410
- > test_remove_all2 : count 5 (remove_all 5 (2::1::4::1::[]) ) = 0
408
+ > test_remove_all2 : count 5 (remove_all 5 [2,1,4,1] ) = 0
411
409
> test_remove_all2 = ?test_remove_all2_rhs
412
410
413
- > test_remove_all3 : count 4 (remove_all 5 (2::1::5::4::1::4::[]) ) = 2
411
+ > test_remove_all3 : count 4 (remove_all 5 [2,1,5,4,1,4] ) = 2
414
412
> test_remove_all3 = ?test_remove_all3_rhs
415
413
416
414
> test_remove_all4 : count 5
417
- > (remove_all 5 (2::1::5::4::5::1::4::5::1::4::[]) ) = 0
415
+ > (remove_all 5 [2,1,5,4,5,1,4,5,1,4] ) = 0
418
416
> test_remove_all4 = ?test_remove_all4_rhs
419
417
420
418
> subset : (s1 : Bag) -> (s2 : Bag) -> Bool
421
419
> subset s1 s2 = ?subset_rhs
422
420
423
- > test_subset1 : subset (1::2::[]) (2::1::4::1::[]) = True
421
+ > test_subset1 : subset [1,2] [2,1,4,1] = True
424
422
> test_subset1 = ?test_subset1_rhs
425
423
426
- > test_subset2 : subset (1::2::2::[]) (2::1::4::1::[]) = False
424
+ > test_subset2 : subset [1,2,2] [2,1,4,1] = False
427
425
> test_subset2 = ?test_subset2_rhs
428
426
429
427
$\square$
@@ -459,8 +457,8 @@ Also, as with numbers, it is sometimes helpful to perform case analysis on the
459
457
possible shapes (empty or non-empty) of an unknown list.
460
458
461
459
> tl_length_pred : (l : NatList) -> pred (length l) = length (tl l)
462
- > tl_length_pred Nil = Refl
463
- > tl_length_pred (Cons n l') = Refl
460
+ > tl_length_pred [] = Refl
461
+ > tl_length_pred (n:: l') = Refl
464
462
465
463
Here, the \idr{Nil} case works because we've chosen to define \idr{tl Nil =
466
464
Nil}. Notice that the case for \idr{Cons} introduces two names, \idr{n} and
@@ -508,8 +506,8 @@ Since larger lists can only be built up from smaller ones, eventually reaching
508
506
lists \idr{l}. Here's a concrete example:
509
507
510
508
> app_assoc : (l1, l2, l3 : NatList) -> ((l1 ++ l2) ++ l3) = (l1 ++ (l2 ++ l3))
511
- > app_assoc Nil l2 l3 = Refl
512
- > app_assoc (Cons n l1') l2 l3 =
509
+ > app_assoc [] l2 l3 = Refl
510
+ > app_assoc (n:: l1') l2 l3 =
513
511
> let inductiveHypothesis = app_assoc l1' l2 l3 in
514
512
> rewrite inductiveHypothesis in Refl
515
513
@@ -562,9 +560,9 @@ use \idr{app} to define a list-reversing function \idr{rev}:
562
560
563
561
> rev : (l : NatList) -> NatList
564
562
> rev Nil = Nil
565
- > rev (h :: t) = (rev t) ++ (h::[])
563
+ > rev (h :: t) = (rev t) ++ [h]
566
564
567
- > test_rev1 : rev (1::2::3::[]) = (3::2::1::[])
565
+ > test_rev1 : rev [1,2,3] = [3,2,1]
568
566
> test_rev1 = Refl
569
567
570
568
> test_rev2 : rev Nil = Nil
@@ -614,7 +612,7 @@ Now we can complete the original proof.
614
612
> rev_length : (l : NatList) -> length (rev l) = length l
615
613
> rev_length Nil = Refl
616
614
> rev_length (n :: l') =
617
- > rewrite app_length (rev l') (n::[]) in
615
+ > rewrite app_length (rev l') [n] in
618
616
> -- Prelude's version of `Induction.plus_comm`
619
617
> rewrite plusCommutative (length (rev l')) 1 in
620
618
> let inductiveHypothesis = rev_length l' in
@@ -762,10 +760,10 @@ equality. Prove that \idr{beq_NatList l l} yields \idr{True} for every list
762
760
> test_beq_NatList1 : beq_NatList Nil Nil = True
763
761
> test_beq_NatList1 = ?test_beq_NatList1_rhs
764
762
765
- > test_beq_NatList2 : beq_NatList (1::2::3::[]) (1::2::3::[]) = True
763
+ > test_beq_NatList2 : beq_NatList [1,2,3] [1,2,3] = True
766
764
> test_beq_NatList2 = ?test_beq_NatList2_rhs
767
765
768
- > test_beq_NatList3 : beq_NatList (1::2::3::[]) (1::2::4::[]) = False
766
+ > test_beq_NatList3 : beq_NatList [1,2,3] [1,2,4] = False
769
767
> test_beq_NatList3 = ?test_beq_NatList3_rhs
770
768
771
769
> beq_NatList_refl : (l : NatList) -> True = beq_NatList l l
@@ -855,13 +853,13 @@ to indicate that it may result in an error.
855
853
> True => Some a
856
854
> False => nth_error l' (pred n)
857
855
858
- > test_nth_error1 : nth_error (4::5::6::7::[]) 0 = Some 4
856
+ > test_nth_error1 : nth_error [4,5,6,7] 0 = Some 4
859
857
> test_nth_error1 = Refl
860
858
861
- > test_nth_error2 : nth_error (4::5::6::7::[]) 3 = Some 7
859
+ > test_nth_error2 : nth_error [4,5,6,7] 3 = Some 7
862
860
> test_nth_error2 = Refl
863
861
864
- > test_nth_error3 : nth_error (4::5::6::7::[]) 9 = None
862
+ > test_nth_error3 : nth_error [4,5,6,7] 9 = None
865
863
> test_nth_error3 = Refl
866
864
867
865
This example is also an opportunity to introduce one more small feature of Idris
@@ -900,10 +898,10 @@ pass a default element for the \idr{Nil} case.
900
898
> test_hd_error1 : hd_error [] = None
901
899
> test_hd_error1 = ?test_hd_error1_rhs
902
900
903
- > test_hd_error2 : hd_error (1::[]) = Some 1
901
+ > test_hd_error2 : hd_error [1] = Some 1
904
902
> test_hd_error2 = ?test_hd_error2_rhs
905
903
906
- > test_hd_error3 : hd_error (5::6::[]) = Some 5
904
+ > test_hd_error3 : hd_error [5,6] = Some 5
907
905
> test_hd_error3 = ?test_hd_error3_rhs
908
906
909
907
$\square$
0 commit comments