Skip to content

Commit b202b4c

Browse files
author
Alex Gryzlov
committed
Edit Poly
1 parent 28ed257 commit b202b4c

File tree

1 file changed

+46
-25
lines changed

1 file changed

+46
-25
lines changed

src/Poly.lidr

Lines changed: 46 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,9 @@ appropriate type parameter:
117117
> test_repeat2 = Refl
118118

119119

120+
\todo[inline]{Explain implicits and {x=foo} syntax first? Move after the
121+
"Supplying Type Arguments Explicitly" section?}
122+
120123
==== Exercise: 2 starsM (mumble_grumble)
121124

122125
> namespace MumbleGrumble
@@ -132,15 +135,14 @@ Consider the following two inductively defined types.
132135
> D : Mumble -> Grumble x
133136
> E : x -> Grumble x
134137

135-
\todo[inline]{Edit, Idris doesn't require type parameters to constructors}
136138
Which of the following are well-typed elements of `Grumble x` for some type `x`?
137139

138140
- `D (B A 5)`
139-
- `D Mumble (B A 5)`
140-
- `D Bool (B A 5)`
141-
- `E Bool True`
142-
- `E Mumble (B C 0)`
143-
- `E Bool (B C 0)`
141+
- `D (B A 5) {x=Mumble}`
142+
- `D (B A 5) {x=Bool}`
143+
- `E True {x=Bool}`
144+
- `E (B C 0) {x=Mumble}`
145+
- `E (B C 0) {x=Bool}`
144146
- `C`
145147

146148
> -- FILL IN HERE
@@ -152,6 +154,9 @@ the lowercase/uppercase distinction.}
152154

153155
==== Type Annotation Inference
154156

157+
\todo[inline]{This has already happened earlier at `repeat`, delete most of
158+
this?}
159+
155160
Let's write the definition of `repeat` again, but this time we won't specify the
156161
types of any of the arguments. Will Idris still accept it?
157162

@@ -180,6 +185,9 @@ code).
180185

181186
==== Type Argument Synthesis
182187

188+
\todo[inline]{We should mention the `_` parameters but it won't work like this
189+
in Idris}
190+
183191
To use a polymorphic function, we need to pass it one or more types in addition
184192
to its other arguments. For example, the recursive call in the body of the
185193
`repeat` function above must pass along the type `x_ty`. But since the second
@@ -244,20 +252,18 @@ Alternatively, we can declare an argument to be implicit when defining the
244252
function itself, by surrounding it in curly braces instead of parens. For
245253
example:
246254

247-
> repeat''' : {x_ty : Type} -> (x : x_ty) -> (count : Nat) -> List x_ty
248-
> repeat''' x Z = Nil
249-
> repeat''' x (S count') = x :: repeat''' x count'
250-
251-
\todo[inline]{Mention that we don't even need the curly-braced argument}
255+
> repeat' : {x_ty : Type} -> (x : x_ty) -> (count : Nat) -> List x_ty
256+
> repeat' x Z = Nil
257+
> repeat' x (S count') = x :: repeat' x count'
252258

253259
(Note that we didn't even have to provide a type argument to the recursive call
254-
to `repeat'''`; indeed, it would be invalid to provide one!)
260+
to `repeat'`; indeed, it would be invalid to provide one!)
255261

256-
We will use the latter style whenever possible, but we will continue to use use
257-
explicit Argument declarations for Inductive constructors. The reason for this
258-
is that marking the parameter of an inductive type as implicit causes it to
259-
become implicit for the type itself, not just for its constructors. For
260-
instance, consider the following alternative definition of the `List` type:
262+
We will use the latter style whenever possible, but we will continue to use
263+
explicit declarations in data types. The reason for this is that marking the
264+
parameter of an inductive type as implicit causes it to become implicit for the
265+
type itself, not just for its constructors. For instance, consider the following
266+
alternative definition of the `List` type:
261267

262268
> data List' : {x : Type} -> Type where
263269
> Nil' : List'
@@ -268,6 +274,16 @@ including `List'` itself, we now have to write just `List'` whether we are
268274
talking about lists of numbers or booleans or anything else, rather than `List'
269275
Nat` or `List' Bool` or whatever; this is a step too far.
270276

277+
\todo[inline]{Added the implicit inference explanation here}
278+
There's another step towards conciseness that we can take in Idris -- drop the
279+
implicit argument completely in function definitions! Idris will automatically
280+
insert them for us when it encounters unknown variables. _Note that by convention
281+
this will only happen for variables starting on a lowercase letter_.
282+
283+
> repeat'' : (x : x_ty) -> (count : Nat) -> List x_ty
284+
> repeat'' x Z = Nil
285+
> repeat'' x (S count') = x :: repeat'' x count'
286+
271287
Let's finish by re-implementing a few other standard list functions on our new
272288
polymorphic lists...
273289

@@ -321,6 +337,9 @@ them as arguments in curly braces.
321337
λΠ> :let mynil' = Nil {elem=Nat}
322338
```
323339

340+
\todo[inline]{Describe here how to bring variables from the type into definition
341+
scope via implicits?}
342+
324343
\todo[inline]{Explain that Idris has built-in notation for lists instead?}
325344

326345
Using argument synthesis and implicit arguments, we can define convenient
@@ -549,11 +568,12 @@ For example, if we apply `filter` to the predicate `evenb` and a list of numbers
549568
> length_is_1 : (l : List x) -> Bool
550569
> length_is_1 l = beq_nat (length l) 1
551570

552-
\todo[inline]{Why doesn't this work?}
571+
\todo[inline]{Why doesn't this work without {x=Nat}?}
553572

554-
> --test_filter2 : filter (length_is_1) [ [1,2], [3], [4], [5,6,7], [], [8] ]
555-
> -- = [ [3], [4], [8] ]
556-
> --test_filter2 = Refl
573+
> test_filter2 : filter (length_is_1 {x=Nat})
574+
> [ [1,2], [3], [4], [5,6,7], [], [8] ]
575+
> = [ [3], [4], [8] ]
576+
> test_filter2 = Refl
557577

558578
We can use `filter` to give a concise version of the `countoddmembers` function
559579
from the `Lists` chapter.
@@ -583,7 +603,7 @@ give each of these functions a name would be tedious.
583603
Fortunately, there is a better way. We can construct a function "on the fly"
584604
without declaring it at the top level or giving it a name.
585605

586-
\todo[inline]{Can't use `*` here due to the tuple sugar interference}
606+
\todo[inline]{Can't use `*` here due to the interference from our tuple sugar}
587607

588608
> test_anon_fun': doit3times (\n => mult n n) 2 = 256
589609
> test_anon_fun' = Refl
@@ -595,7 +615,7 @@ Here is the `filter` example, rewritten to use an anonymous function.
595615

596616
> test_filter2': filter (\l => beq_nat (length l) 1)
597617
> [ [1,2], [3], [4], [5,6,7], [], [8] ]
598-
> = [ [3], [4], [8] ]
618+
> = [ [3], [4], [8] ]
599619
> test_filter2' = Refl
600620

601621

@@ -813,7 +833,8 @@ supply just the first. This is called _partial application_.
813833
> test_plus3 : plus3 4 = 7
814834
> test_plus3 = Refl
815835

816-
\todo[inline]{Why is this broken?}
836+
\todo[inline]{Why is this broken? `the (doit3times plus3 0 = 9) Refl` works in
837+
REPL}
817838

818839
> -- test_plus3' : doit3times plus3 0 = 9
819840
> -- test_plus3' = Refl
@@ -1018,7 +1039,7 @@ Multiplication:
10181039

10191040
Exponentiation:
10201041

1021-
\todo[inline]{Edit hint}
1042+
\todo[inline]{Edit the hint.}
10221043

10231044
(Hint: Polymorphism plays a crucial role here. However, choosing the right type
10241045
to iterate over can be tricky. If you hit a "Universe inconsistency" error, try

0 commit comments

Comments
 (0)