Skip to content

Commit 0764f09

Browse files
committed
Fix tut07 formatting
1 parent a58d83b commit 0764f09

1 file changed

Lines changed: 20 additions & 20 deletions

File tree

tutorials/07_test-doc-debug.md

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ There are many predefined expectation functions that are typically written in in
168168

169169
* `shouldBe` = equality test
170170
* `shouldNotBe` = inequality test
171-
* `shouldSatisfy` = test if result satisfies given property as function `:: a -> Bool`
171+
* `shouldSatisfy` = test if result satisfies given property as function of type `a -> Bool`
172172
* `shouldStartWith` = test if list has a given prefix
173173
* `shouldEndWith` = test if list has a given suffix
174174
* `shouldContain` = test if list contains sublist
@@ -352,7 +352,7 @@ You can leverage the documentation also to explain design decisions, trade-offs,
352352

353353
### Documenting functions
354354

355-
Haddock comments use -- | for single-line documentation and {-| ... -} for multi-line blocks. For functions, you should document:
355+
Haddock comments use `-- |` for single-line documentation and `{-| ... -}` for multi-line blocks. For functions, you should document:
356356

357357
```haskell
358358
-- | Computes the arithmetic mean of a non-empty list.
@@ -483,7 +483,7 @@ import Debug.Trace (traceShowId)
483483

484484
foo xs = traceShowId (take 5 xs) ++ "..."
485485
```
486-
* Use `traceM`/`traceIO` when you're in monadic code (IO, StateT, etc.). The file already points out `traceIO` and `traceM` as standard options.
486+
* Use `traceM`/`traceIO` when you're in monadic code (`IO`, `StateT`, etc.). The file already points out `traceIO` and `traceM` as standard options.
487487
* Laziness gotcha: sometimes nothing prints because the value isn't demanded yet. If you expect a trace and don't see it, ensure the expression is actually evaluated (e.g., by printing it, using `evaluate`, or by restructuring so it's forced).
488488
* Keep traces out of releases: a common pattern is to guard them behind a CPP flag, or keep them local and remove them once fixed.
489489

@@ -543,7 +543,7 @@ This example is not chosen because it is practical, but because it clearly demon
543543
* a reasonable algorithm,
544544
* and low-level optimizations.
545545

546-
### 1. Naive Fibonacci
546+
### Case 0: Naive Fibonacci
547547

548548
```haskell
549549
fibonacci :: Integer -> Integer
@@ -741,7 +741,7 @@ main = do
741741
print (sumGood [1..10000000])
742742
```
743743

744-
### 2. The biggest optimization: a better algorithm
744+
### Case 1: The biggest optimization: a better algorithm
745745

746746
The main problem with the naive Fibonacci implementation is not laziness, boxing, or the choice of numeric type. The real problem is the **algorithm itself**.
747747

@@ -771,7 +771,7 @@ Now we can benchmark and profile these implementations to see the dramatic impro
771771
772772
Low-level optimizations can improve a good implementation, but they rarely compensate for a poor algorithm.
773773

774-
### 3. Strict evaluation
774+
### Case 2: Strict evaluation
775775

776776
Even after choosing a much better algorithm, evaluation strategy still matters.
777777

@@ -804,7 +804,7 @@ The important lesson is that strictness is usually a secondary optimization:
804804

805805
Strictness can make a good implementation better, but it does not change the fundamental complexity of the problem.
806806

807-
### 4. Choosing the right types
807+
### Case 3: Choosing the right types
808808

809809
The next question is whether we are using the most appropriate data type.
810810

@@ -835,7 +835,7 @@ However, `Int` has a fixed size and can overflow. That means it is only appropri
835835

836836
Choosing the right type will usually not matter as much as choosing the right algorithm, but it can still provide a noticeable improvement once the algorithm is already good. This is of course different when it comes to **types of data structures**, where the choice of representation can have a significant impact on performance.
837837

838-
### 5. Boxed vs unboxed values (advanced)
838+
### Case 4: Boxed vs unboxed values (advanced)
839839

840840
Another source of overhead in Haskell is how values are represented in memory.
841841

@@ -911,7 +911,7 @@ main = print (fibonacciUnboxed 30)
911911

912912
Note that we are using `Int` and cannot use `Integer` here, because `Integer` is a boxed type and cannot be unboxed. This code is more efficient than the boxed version, but it is also more complex and less flexible. It is generally recommended to let GHC handle unboxing for you by writing clear, strict code with appropriate types.
913913

914-
### 6. Compiler optimizations
914+
### Case 5: Compiler optimizations
915915

916916
So far, all improvements were made by changing the source code. However, the compiler itself can significantly improve performance.
917917

@@ -938,7 +938,7 @@ ghc-options:
938938
- -O2
939939
```
940940
941-
### 7. Parallelism and concurrency
941+
### Case 6: Parallelism and concurrency
942942
943943
Another possible optimization is to use multiple CPU cores. This can help when:
944944
@@ -1120,7 +1120,7 @@ stack exec -- fib-par -- +RTS -N4
11201120

11211121
Here, `-N` uses all available cores, while `-N4` limits it to 4 cores. Without this option, the program may still use concurrency abstractions, but it will not execute pure computations in parallel across multiple cores.
11221122

1123-
### 8. Foreign Function Interface (FFI)
1123+
### Case 7: Foreign Function Interface (FFI)
11241124

11251125
Another way to improve performance, or to reuse existing code, is to call functions written in another language.
11261126

@@ -1429,14 +1429,14 @@ The homework to practice IO (again), testing, and writing project documentation
14291429
14301430
## Further reading
14311431
1432-
* [A Gentle Introduction to Haskell - Input/Output](https://www.haskell.org/tutorial/io.html)
1433-
* [Haskell - Simple input and output](https://en.wikibooks.org/wiki/Haskell/Simple_input_and_output)
1434-
* [Real World Haskell - Testing and quality assurance](http://book.realworldhaskell.org/read/testing-and-quality-assurance.html)
1435-
* [WikiBooks - Haskell: Testing](https://en.wikibooks.org/wiki/Haskell/Testing)
1432+
* [A Gentle Introduction to Haskell: Input/Output](https://www.haskell.org/tutorial/io.html)
1433+
* [Haskell: Simple input and output](https://en.wikibooks.org/wiki/Haskell/Simple_input_and_output)
1434+
* [Real World Haskell: Testing and quality assurance](http://book.realworldhaskell.org/read/testing-and-quality-assurance.html)
1435+
* [WikiBooks Haskell: Testing](https://en.wikibooks.org/wiki/Haskell/Testing)
14361436
* [Haddock User Guide](https://www.haskell.org/haddock/doc/html/index.html)
14371437
* [QuickCheck and Magic of Testing](https://www.fpcomplete.com/blog/2017/01/quickcheck)
1438-
* [Haskell - Debugging](https://wiki.haskell.org/Debugging)
1439-
* [Haskell - Performance](https://wiki.haskell.org/Performance)
1440-
* [Haskell - Concurrency](https://wiki.haskell.org/Concurrency)
1441-
* [Real World Haskell - Concurrent and Multicore Programming](http://book.realworldhaskell.org/read/concurrent-and-multicore-programming.html)
1442-
* [GHC - Concurrent and Parallel Haskell](https://downloads.haskell.org/~ghc/7.0.3/docs/html/users_guide/lang-parallel.html)
1438+
* [Haskell: Debugging](https://wiki.haskell.org/Debugging)
1439+
* [Haskell: Performance](https://wiki.haskell.org/Performance)
1440+
* [Haskell: Concurrency](https://wiki.haskell.org/Concurrency)
1441+
* [Real World Haskell: Concurrent and Multicore Programming](http://book.realworldhaskell.org/read/concurrent-and-multicore-programming.html)
1442+
* [GHC: Concurrent and Parallel Haskell](https://downloads.haskell.org/~ghc/7.0.3/docs/html/users_guide/lang-parallel.html)

0 commit comments

Comments
 (0)