Skip to content

Commit 27ae6a9

Browse files
committed
typo: fix contraction of "let us"
1 parent 8bf919a commit 27ae6a9

8 files changed

+46
-46
lines changed

src/Tutorial_02_Logic.lhs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,7 @@ sophisticated abstractions.]
274274
Examples: Propositions
275275
----------------------
276276
277-
Finally, lets conclude this quick overview with some
277+
Finally, let's conclude this quick overview with some
278278
examples of predicates, in order to build up our own
279279
intuition about logic and validity.
280280
Each of the below is a predicate from our refinement
@@ -390,7 +390,7 @@ exDeMorgan2 a b = not (a && b) <=> (not a && not b)
390390
Examples: Arithmetic
391391
--------------------
392392
393-
Next, lets look at some predicates involving arithmetic.
393+
Next, let's look at some predicates involving arithmetic.
394394
The simplest ones don't have any variables, for example:
395395
396396
\begin{code}
@@ -487,8 +487,8 @@ fx1 f x = (x == f (f (f x)))
487487
==> (x == f x)
488488
\end{code}
489489
490-
To get a taste of why uninterpreted functions will prove useful
491-
lets write a function to compute the `size` of a list:
490+
To get a taste of why uninterpreted functions will prove useful,
491+
let's write a function to compute the `size` of a list:
492492
493493
\begin{code}
494494
{-@ measure size @-}
@@ -546,5 +546,5 @@ mean by the term *logical predicate*.
546546
and evaluating the predicates (which would take forever!) but instead
547547
by using clever symbolic algorithms.
548548
549-
Next, lets see how we can use logical predicates to *specify* and
549+
Next, let's see how we can use logical predicates to *specify* and
550550
*verify* properties of real programs.

src/Tutorial_05_Datatypes.lhs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -288,12 +288,12 @@ badList = 2 :< 1 :< 3 :< Emp -- rejected by LH
288288
289289
\noindent
290290
It's all very well to *specify* ordered lists.
291-
Next, lets see how it's equally easy to *establish*
291+
Next, let's see how it's equally easy to *establish*
292292
these invariants by implementing several textbook
293293
sorting routines.
294294
295295
\newthought{Insertion Sort}
296-
First, lets implement insertion sort, which converts an ordinary
296+
First, let's implement insertion sort, which converts an ordinary
297297
list `[a]` into an ordered list `IncList a`.
298298
299299
\begin{code}
@@ -527,11 +527,11 @@ add k' t@(Node k l r)
527527
| otherwise = t
528528
\end{code}
529529
530-
\newthought{Minimum} For our next trick, lets write a function to delete the *minimum*
531-
element from a `BST`. This function will return a *pair* of outputs --
532-
the smallest element and the remainder of the tree. We can say that the
530+
\newthought{Minimum} For our next trick, let's write a function to delete the
531+
*minimum* element from a `BST`. This function will return a *pair* of outputs
532+
-- the smallest element and the remainder of the tree. We can say that the
533533
output element is indeed the smallest, by saying that the remainder's
534-
elements exceed the element. To this end, lets define a helper type:
534+
elements exceed the element. To this end, let's define a helper type:
535535
^[This helper type approach is rather verbose.
536536
We should be able to just use plain old pairs
537537
and specify the above requirement as a *dependency*

src/Tutorial_06_Measure_Bool.lhs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ Boolean Measures {#boolmeasures}
55

66
In the last two chapters, we saw how refinements could be used to
77
reason about the properties of basic `Int` values like vector
8-
indices, or the elements of a list. Next, lets see how we can
8+
indices, or the elements of a list. Next, let's see how we can
99
describe properties of aggregate structures like lists and trees,
1010
and use these properties to improve the APIs for operating over
1111
such structures.
@@ -74,7 +74,7 @@ avg3 x y z = divide (x + y + z) 3
7474
\end{code}
7575
7676
\noindent However, it can be more of a challenge when the divisor
77-
is obtained *dynamically*. For example, lets write a function to
77+
is obtained *dynamically*. For example, let's write a function to
7878
find the number of elements in a list
7979
8080
\begin{code}
@@ -117,7 +117,7 @@ Lifting Functions to Measures {#usingmeasures}
117117
118118
\newthought{How} shall we tell LiquidHaskell that a list is *non-empty*?
119119
Recall the notion of `measure` previously [introduced](#vectorbounds)
120-
to describe the size of a `Data.Vector`. In that spirit, lets write
120+
to describe the size of a `Data.Vector`. In that spirit, let's write
121121
a function that computes whether a list is not empty:
122122
123123
\begin{code}
@@ -387,7 +387,7 @@ In this chapter we saw how LiquidHaskell lets you
387387
often clutter implementations and specifications.
388388
389389
\noindent
390-
Of course, we can do a lot more with measures, so lets press on!
390+
Of course, we can do a lot more with measures, so let's press on!
391391
392392
393393

src/Tutorial_07_Measure_Int.lhs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ we will use this API to implement K-means clustering.]
6868
Wholemeal Programming
6969
---------------------
7070
71-
Indexitis begone! As an example of wholemeal programming, lets
71+
Indexitis begone! As an example of wholemeal programming, let's
7272
write a small library that represents vectors as lists and
7373
matrices as nested vectors:
7474
@@ -211,7 +211,7 @@ We are almost ready to begin creating a dimension aware API
211211
for lists; one last thing that is useful is a couple of aliases
212212
for describing lists of a given dimension.
213213
214-
\newthought{To make signatures symmetric} lets define an alias for
214+
\newthought{To make signatures symmetric} let's define an alias for
215215
plain old (unrefined) lists:
216216
217217
\begin{code}
@@ -345,7 +345,7 @@ test3 = zipOrNull ["cat", "dog"] []
345345
Lists: Size Reducing API {#listreducing}
346346
------------------------
347347
348-
Next, lets look at some functions that truncate lists, in one way or another.
348+
Next, let's look at some functions that truncate lists, in one way or another.
349349
350350
\newthought{Take} lets us grab the first `k` elements from a list:
351351
@@ -685,7 +685,7 @@ mat23 = matFromList [ [1, 2]
685685
How will you figure out the number of columns? A measure
686686
may be useful.
687687
688-
\newthought{Matrix Multiplication} Finally, lets implement matrix
688+
\newthought{Matrix Multiplication} Finally, let's implement matrix
689689
multiplication. You'd think we did it already, but in fact the
690690
implementation at the top of this chapter is all wrong (run it and
691691
see!) We cannot just multiply any two matrices: the number of

src/Tutorial_08_Measure_Set.lhs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -70,15 +70,15 @@ Examples of this abound: for example, we'd like to know that:
7070
\newthought{SMT Solvers} support very expressive logics.
7171
In addition to linear arithmetic and uninterpreted functions,
7272
they can [efficiently decide][smt-set] formulas over sets.
73-
Next, lets see how LiquidHaskell lets us exploit this fact
73+
Next, let's see how LiquidHaskell lets us exploit this fact
7474
to develop types and interfaces that guarantee invariants
7575
over the set of elements of a structures.
7676
7777
Talking about Sets
7878
------------------
7979
8080
First, we need a way to talk about sets in the refinement logic. We could
81-
roll our own special Haskell type but for now, lets just use the `Set a`
81+
roll our own special Haskell type but for now, let's just use the `Set a`
8282
type from the prelude's `Data.Set`.^[See [this](https://ucsd-progsys.github.io/liquidhaskell-blog/2013/03/26/talking-about-sets.lhs/)
8383
for a brief description of how to work directly with the set operators natively
8484
supported by LiquidHaskell.]
@@ -114,7 +114,7 @@ to learn how modern SMT solvers prove equalities like the above.]
114114
Proving QuickCheck Style Properties {#quickcheck}
115115
-----------------------------------
116116
117-
To get the hang of whats going on, lets do a few warm up exercises,
117+
To get the hang of whats going on, let's do a few warm up exercises,
118118
using LiquidHaskell to prove various simple theorems about sets
119119
and operations over them.
120120
@@ -206,7 +206,7 @@ prop_union_assoc x y z
206206
207207
\newthought{The Distributivity Laws} for Boolean Algebra can
208208
be verified by writing properties over the relevant operators.
209-
For example, we lets check that `intersection` distributes over `union`:
209+
For example, let's check that `intersection` distributes over `union`:
210210
211211
\begin{code}
212212
{-@ prop_intersection_dist :: _ -> _ -> _ -> True @-}
@@ -398,10 +398,10 @@ test2 = elem 2 [1, 3]
398398
Permutations
399399
------------
400400
401-
Next, lets use the refined list API to prove that
401+
Next, let's use the refined list API to prove that
402402
various sorting routines return *permutations*
403403
of their inputs, that is, return output lists whose
404-
elements are the *same as* those of the input lists.^[Since we are focusing on the elements, lets not
404+
elements are the *same as* those of the input lists.^[Since we are focusing on the elements, let's not
405405
distract ourselves with the [ordering invariant](#orderedlists)
406406
and reuse plain old lists. See [this](http://goto.ucsd.edu/~rjhala/liquid/haskell/blog/blog/2013/07/29/putting-things-in-order.lhs/)
407407
for how to specify and verify order with plain old lists.]
@@ -486,7 +486,7 @@ handles or system resources can create unpleasant leaks.
486486
For example, the [xmonad][xmonad] window manager creates a
487487
sophisticated *zipper* data structure to hold the list of
488488
active user windows and carefully maintains the invariant
489-
that that the zipper contains no duplicates. Next, lets see how to
489+
that that the zipper contains no duplicates. Next, let's see how to
490490
specify and verify this invariant using LiquidHaskell, first for
491491
lists, and then for a simplified zipper.
492492

src/Tutorial_10_Case_Study_Associative_Maps.lhs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ that tracks the set of keys stored in the map, in order to
9595
statically ensure the safety of lookups.
9696
9797
\newthought{Types} First, we need a type for `Map`s. As usual,
98-
lets parameterize the type with `k` for the type of keys and
98+
let's parameterize the type with `k` for the type of keys and
9999
`v` for the type of values:
100100
101101
~~~~~{.spec}
@@ -160,7 +160,7 @@ Using Maps: Well Scoped Expressions
160160
-----------------------------------
161161
162162
Rather than jumping into the *implementation* of the above `Map` API,
163-
lets write a *client* that uses `Map`s to implement an interpreter for
163+
let's write a *client* that uses `Map`s to implement an interpreter for
164164
a tiny language. In particular, we will use maps as an *environment*
165165
containing the values of *bound variables*, and we will use the refined
166166
API to ensure that *lookups never fail*, and hence, that well-scoped
@@ -351,11 +351,11 @@ Implementing Maps: Binary Search Trees {#lemmas}
351351
We just saw how easy it is to *use* the Associative
352352
Map [API](#mapapi) to ensure the safety of lookups,
353353
even though the `Map` has a "dynamically" generated
354-
set of keys. Next, lets see how we can *implement*
354+
set of keys. Next, let's see how we can *implement*
355355
a `Map` library that respects the API using
356356
[Binary Search Trees](#binarysearchtree)
357357
358-
\newthought{Data Type} First, lets provide an
358+
\newthought{Data Type} First, let's provide an
359359
implementation of the hitherto abstract data
360360
type for `Map`. We shall use Binary Search Trees,
361361
wherein, at each `Node`, the `left` (resp. `right`)
@@ -424,7 +424,7 @@ set k' v' (Node k v l r)
424424
set k' v' Tip = Node k' v' Tip Tip
425425
\end{code}
426426
427-
\newthought{Lookup} Next, lets write the `mem` function that returns
427+
\newthought{Lookup} Next, let's write the `mem` function that returns
428428
the value associated with a key `k'`. To do so we just compare `k'`
429429
with the root key, if they are equal, we return the binding, and
430430
otherwise we go down the `left` (resp. `right`) subtree if sought for
@@ -445,7 +445,7 @@ get' _ Tip = die "Lookup Never Fails"
445445
\newthought{Unfortunately} the function above is *rejected*
446446
by LiquidHaskell. This is a puzzler (and a bummer!) because
447447
in fact it *is* correct. So what gives?
448-
Well, lets look at the error for the call `get' k' l`
448+
Well, let's look at the error for the call `get' k' l`
449449
450450
~~~~~{.liquiderror}
451451
src/07-case-study-associative-maps.lhs:411:25: Error: Liquid Type Mismatch
@@ -461,7 +461,7 @@ Well, lets look at the error for the call `get' k' l`
461461
~~~~~
462462
463463
\noindent LiquidHaskell is *unable* to deduce that the key `k'`
464-
definitely belongs in the `left` subtree `l`. Well, lets ask ourselves:
464+
definitely belongs in the `left` subtree `l`. Well, let's ask ourselves:
465465
*why* must `k'` belong in the left subtree? From the input, we know
466466
`HasKey k' m` i.e. that `k'` is *somewhere* in `m`.
467467
That is *one of* the following holds:

src/Tutorial_11_Case_Study_Pointers.lhs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ HeartBleeds in Haskell
7777
\newthought{Modern Languages} like Haskell are ultimately built upon the
7878
foundation of `C`. Thus, implementation errors could open up unpleasant
7979
vulnerabilities that could easily slither past the type system and even
80-
code inspection. As a concrete example, lets look at a function that
80+
code inspection. As a concrete example, let's look at a function that
8181
uses the `ByteString` library to truncate strings:
8282
8383
\begin{code}
@@ -134,14 +134,14 @@ a hierarchy of levels (i.e. modules). Here, we have three levels:
134134
135135
\noindent Our strategy, as before, is to develop an *refined API* for
136136
each level such that errors at each level are prevented by using the typed
137-
interfaces for the lower levels. Next, lets see how this strategy lets us
137+
interfaces for the lower levels. Next, let's see how this strategy lets us
138138
safely manipulate pointers.
139139
140140
Low-level Pointer API
141141
---------------------
142142
143-
To get started, lets look at the low-level pointer API that is
144-
offered by GHC and the run-time. First, lets see who the
143+
To get started, let's look at the low-level pointer API that is
144+
offered by GHC and the run-time. First, let's see who the
145145
*dramatis personae* are and how they might let heartbleeds in.
146146
Then we will see how to batten down the hatches with LiquidHaskell.
147147
@@ -203,7 +203,7 @@ operation `plusPtr p off` which takes a pointer `p` an integer
203203
plusPtr :: Ptr a -> Int -> Ptr b
204204
~~~~~
205205
206-
\newthought{Example} That was rather dry; lets look at a concrete
206+
\newthought{Example} That was rather dry; let's look at a concrete
207207
example of how one might use the low-level API. The following
208208
function allocates a block of 4 bytes and fills it with zeros:
209209
@@ -437,7 +437,7 @@ but that is outside the scope of LiquidHaskell.]
437437
ByteString API
438438
--------------
439439
440-
Next, lets see how the low-level API can be used to implement
440+
Next, let's see how the low-level API can be used to implement
441441
to implement [ByteStrings][bytestring], in a way that lets us
442442
perform fast string operations without opening the door to
443443
overflows.
@@ -490,7 +490,7 @@ to the legality requirements that the start and end of the `ByteString`
490490
be *within* the block of memory referred to by `bPtr`.
491491
492492
493-
\newthought{For brevity} lets define an alias for `ByteString`s of
493+
\newthought{For brevity} let's define an alias for `ByteString`s of
494494
a given size:
495495
496496
\begin{code}
@@ -700,7 +700,7 @@ How *big* is the output list in terms of `p`, `n` and `acc`.
700700
Application API
701701
---------------
702702
703-
Finally, lets revisit our potentially "bleeding" `chop` function to
703+
Finally, let's revisit our potentially "bleeding" `chop` function to
704704
see how the refined `ByteString` API can prevent errors. We require
705705
that the prefix size `n` be less than the size of the input string `s`:
706706

src/Tutorial_12_Case_Study_AVL.lhs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ Specifying AVL Trees
139139
--------------------
140140
141141
The tricky bit is to ensure order and balance. Before we can ensure
142-
anything, lets tell LiquidHaskell what we mean by these terms, by
142+
anything, let's tell LiquidHaskell what we mean by these terms, by
143143
defining legal or valid AVL trees.
144144
145145
\newthought{To Specify Order} we just define two aliases `AVLL` and `AVLR`
@@ -218,7 +218,7 @@ Smart Constructors
218218
------------------
219219
220220
Lets use the type to construct a few small trees which will
221-
also be handy in a general collection API. First, lets write
221+
also be handy in a general collection API. First, let's write
222222
an alias for trees of a given height:
223223
224224
\begin{code}
@@ -282,7 +282,7 @@ the properties it requires and ensures.
282282
Inserting Elements
283283
------------------
284284
285-
Next, lets turn our attention to the problem of *adding* elements to
285+
Next, let's turn our attention to the problem of *adding* elements to
286286
an `AVL` tree. The basic strategy is this:
287287
288288
1. *Find* the appropriate location (per ordering) to add the value,
@@ -624,7 +624,7 @@ insR = undefined
624624
Refactoring Rebalance
625625
---------------------
626626
627-
Next, lets write a function to `delete` an element from a tree.
627+
Next, let's write a function to `delete` an element from a tree.
628628
In general, we can apply the same strategy as `insert`:
629629
630630
1. remove the element without worrying about heights,
@@ -639,7 +639,7 @@ is *inside* the `insL` which does the insertion as well.
639639
This is correct, but it means we would have to *repeat* the case
640640
analysis when deleting a value, which is unfortunate.
641641
642-
\newthought{Instead lets refactor} the rebalancing code into a
642+
\newthought{Instead let's refactor} the rebalancing code into a
643643
separate function, that can be used by *both* `insert` and `delete`.
644644
It looks like this:
645645

0 commit comments

Comments
 (0)