@@ -36,8 +36,31 @@ How could we even describe such a precondition?
3636## Length-Indexed Lists
3737
3838The answer to the issues described above is of course: Dependent types.
39- And the most common introductory example is the * vector* : A list indexed
40- by its length:
39+ Before we proceed to our example, first consider how Idris recursively
40+ defines the natural numbers (here affixed with apostrophes to avoid introducing
41+ a conflict with the actual definition of ` Nat ` , which you can find
42+ [ here] ( https://github.com/idris-lang/Idris-dev/blob/master/libs/prelude/Prelude/Nat.idr )
43+ for reference)):
44+
45+ ``` idris
46+ data Nat' : Type where
47+ Z' : Nat'
48+ S' : Nat' -> Nat'
49+ ```
50+
51+ In this scheme, 0 is represented by ` Z ` , 1 is represented by ` S Z ` , 2 is
52+ represented by ` S (S Z) ` , and so on. Idris does this automatically so if you
53+ enter ` Z ` or ` S Z ` into the REPL, it will return ` 0 ` or ` 1 ` . Note that the
54+ only function inherently available to act on a value of type ` Nat ` is our data
55+ constructor ` S ` , which represents the successor function, i.e. adding 1.
56+
57+ Also note that in Idris, every ` Nat ` can be represented as either a ` Z ` or
58+ an ` S n ` where ` n ` is another ` Nat ` . Much as every ` List a ` can be represented
59+ as either a ` Nil ` or an ` x :: xs ` (where ` x ` is an ` a ` and ` xs ` is a ` List a ` ),
60+ this informs our pattern matching when solving problems.
61+
62+ Now we can consider the textbook introductory example of dependent types,
63+ the * vector* , which is a list indexed by its length:
4164
4265``` idris
4366data Vect : (len : Nat) -> (a : Type) -> Type where
@@ -443,7 +466,10 @@ this, which constructor(s) of the type family to use.
443466
444467### Exercises part 1
445468
446- 1 . Implement function ` head ` for non-empty vectors:
469+ 1 . Implement a function ` len : List a -> Nat ` for calculating the
470+ length of a ` List ` . For example, ` len [1, 1, 1] ` produces ` 3 ` .
471+
472+ 2 . Implement function ` head ` for non-empty vectors:
447473
448474 ``` idris
449475 head : Vect (S n) a -> a
@@ -455,27 +481,27 @@ this, which constructor(s) of the type family to use.
455481 a ` Maybe ` ! Make sure to add an ` impossible ` clause for the ` Nil `
456482 case (although this is not strictly necessary here).
457483
458- 2 . Using ` head ` as a reference, declare and implement function ` tail `
484+ 3 . Using ` head ` as a reference, declare and implement function ` tail `
459485 for non-empty vectors. The types should reflect that the output
460486 is exactly one element shorter than the input.
461487
462- 3 . Implement ` zipWith3 ` . If possible, try to doing so without looking at
488+ 4 . Implement ` zipWith3 ` . If possible, try to doing so without looking at
463489 the implementation of ` zipWith ` :
464490
465491 ``` idris
466492 zipWith3 : (a -> b -> c -> d) -> Vect n a -> Vect n b -> Vect n c -> Vect n d
467493 ```
468494
469- 4 . Declare and implement a function ` foldSemi `
495+ 5 . Declare and implement a function ` foldSemi `
470496 for accumulating the values stored
471497 in a ` List ` through ` Semigroup ` s append operator (` (<+>) ` ).
472498 (Make sure to only use a ` Semigroup ` constraint, as opposed to
473499 a ` Monoid ` constraint.)
474500
475- 5 . Do the same as in Exercise 4, but for non-empty vectors. How
501+ 6 . Do the same as in Exercise 4, but for non-empty vectors. How
476502 does a vector's non-emptiness affect the output type?
477503
478- 6 . Given an initial value of type ` a ` and a function ` a -> a ` ,
504+ 7 . Given an initial value of type ` a ` and a function ` a -> a ` ,
479505 we'd like to generate ` Vect ` s of ` a ` s, the first value of
480506 which is ` a ` , the second value being ` f a ` , the third
481507 being ` f (f a) ` and so on.
@@ -487,7 +513,7 @@ this, which constructor(s) of the type family to use.
487513 encapsulate this behavior. Get some inspiration from ` replicate `
488514 if you don't know where to start.
489515
490- 7 . Given an initial value of a state type ` s ` and
516+ 8 . Given an initial value of a state type ` s ` and
491517 a function ` fun : s -> (s,a) ` ,
492518 we'd like to generate ` Vect ` s of ` a ` s. Declare and implement
493519 function ` generate ` , which should encapsulate this behavior. Make sure to use
@@ -501,7 +527,7 @@ this, which constructor(s) of the type family to use.
501527 [1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
502528 ```
503529
504- 8 . Implement function ` fromList ` , which converts a list of
530+ 9 . Implement function ` fromList ` , which converts a list of
505531 values to a ` Vect ` of the same length. Use holes if you
506532 get stuck:
507533
@@ -513,7 +539,7 @@ this, which constructor(s) of the type family to use.
513539 length of the resulting vector by passing the list argument
514540 to function * length* .
515541
516- 9 . Consider the following declarations:
542+ 10 . Consider the following declarations:
517543
518544 ``` idris
519545 maybeSize : Maybe a -> Nat
0 commit comments