@@ -206,21 +206,7 @@ \section{A basic solution pipeline}
206
206
207
207
\begin {figure }
208
208
\centering
209
- \begin {minted }{haskell}
210
- import Control.Arrow ((>>>))
211
-
212
- main = interact $ parse >>> map solve >>> format
213
-
214
- parse :: String -> [[Integer]]
215
- parse = _
216
-
217
- solve :: [Integer] -> Integer
218
- solve = _
219
-
220
- format :: [Integer] -> String
221
- format = _
222
- \end {minted}
223
- % $
209
+ \inputminted {haskell}{code/intro/Skeleton.hs}
224
210
\caption {A skeleton solution for A Different Problem}
225
211
\label {fig:skeleton-different }
226
212
\end {figure }
@@ -299,10 +285,7 @@ \section{Parsing and formatting}
299
285
300
286
\begin {figure }
301
287
\centering
302
- \begin {minted}{haskell}
303
- parse :: String -> [[Integer]]
304
- parse = lines >>> map (words >>> map read)
305
- \end {minted}
288
+ \inputminted [firstline=5, lastline=6]{haskell}{code/intro/Different.hs}
306
289
\caption {\h {parse} function for A Different Problem}
307
290
\label {fig:parse-different }
308
291
\end {figure }
@@ -347,6 +330,8 @@ \section{Parsing and formatting}
347
330
need to use provided information about the length of each test case.
348
331
We will discuss such parsing in \pref {chap:parsing }.
349
332
333
+ \todo {include full solution for A Different Problem?}
334
+
350
335
\section {Using partial functions }
351
336
\label {sec:partial }
352
337
@@ -429,22 +414,13 @@ \section{Example: processing a list of strings}
429
414
the list of words, updating an accumulator variable every time we see
430
415
a string that does not contain the letter e. An inexperienced
431
416
Haskeller might produce something similar:
432
- \begin {minted}{haskell}
433
- lengthWithoutE :: [String] -> Int
434
- lengthWithoutE [] = 0
435
- lengthWithoutE (s:ss)
436
- | 'e' `elem` s = lengthWithoutE ss
437
- | otherwise = length s + lengthWithoutE ss
438
- \end {minted}
417
+ \inputminted {haskell}{code/wholemeal/LengthWithoutE.hs}
439
418
This code works, but there is a better way. Instead of thinking in
440
419
terms of processing the list one item at a time, an experienced
441
420
Haskeller will think in terms of incrementally transforming the input
442
421
into the desired output: first, filter out the strings we don't want;
443
422
next, turn each string into its length; and finally sum the lengths.
444
- \begin {minted}{haskell}
445
- lengthWithoutE' :: [String] -> Int
446
- lengthWithoutE' = filter ('e' `notElem`) >>> map length >>> sum
447
- \end {minted}
423
+ \inputminted {haskell}{code/wholemeal/LengthWithoutEWholemeal.hs}
448
424
This is better in almost every way: it is shorter, easier to read and
449
425
understand, easier to refactor, harder to get wrong, and easier to
450
426
prove correct.
@@ -494,6 +470,9 @@ \subsection{Lists}
494
470
lists with $ 10 ^5 $ elements each is probably fine; having $ 10 ^5 $ lists
495
471
with two elements each is probably going to be too slow.
496
472
473
+ \todo {pick two or three representative sample problems and discuss
474
+ their solutions? One using scanl?}
475
+
497
476
\kattis {foo, bar}
498
477
499
478
\subsection {Sets }
@@ -546,26 +525,7 @@ \subsubsection{Example: Booking a Room}
546
525
547
526
\begin {figure }
548
527
\centering
549
- \begin {minted}{haskell}
550
- import Control.Arrow ((>>>))
551
- import qualified Data.Set as S
552
-
553
- main :: IO ()
554
- main = interact $ words >>> parse >>> solve
555
-
556
- data Hotel = Hotel
557
- { numRooms :: Int
558
- , booked :: [Int]
559
- }
560
-
561
- parse :: [String] -> Hotel
562
- parse (r:_:rs) = Hotel (read r) (map read rs)
563
-
564
- solve :: Hotel -> String
565
- solve (Hotel r rs) =
566
- maybe "too late" show . S.lookupMin
567
- $ S.fromList [1 ..r] `S.difference` S.fromList rs
568
- \end {minted}
528
+ \inputminted {haskell}{code/wholemeal/BookingARoom.hs}
569
529
\caption {Booking a Room solution}
570
530
\label {fig:bookingaroom }
571
531
\end {figure }
@@ -1001,10 +961,12 @@ \section{ByteString}
1001
961
\end {minted}
1002
962
Now we're talking---this version completes in a blazing 0.04 seconds!
1003
963
1004
- % We can take these principles and use them to make a variant of the
1005
- % `Scanner` module from last time which uses (lazy, ASCII) `ByteString`
1006
- % instead of `String`, including the use of the `readInt` functions to
1007
- % read `Int` values quickly. You can [find it here](https://github.com/byorgey/comprog-hs/blob/master/ScannerBS.hs).
964
+ We can take these principles and use them to make a variant of the
965
+ \h {Scanner} module from last time which uses (lazy, ASCII)
966
+ \h {ByteString} instead of \h {String}, including the use of the
967
+ \h {readInt} functions to read \h {Int} values quickly. You can [find
968
+ it
969
+ here](https://github.com/byorgey/comprog-hs/blob/master/ScannerBS.hs).
1008
970
1009
971
\chapter {Monoids}
1010
972
\label {chap:monoids}
0 commit comments