You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: _chapters/haskell1.md
+18-20Lines changed: 18 additions & 20 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -237,9 +237,23 @@ But there are definitely cons:
237
237
- It can be hard to reason about runtime performance
238
238
- Mixing up strict and lazy evaluation (which can happen inadvertently) can lead to (for example) O(n<sup>2</sup>) behaviour in what should be linear time processing.
239
239
240
-
---
240
+
## Lazy infinite lists
241
241
242
-
### A Side Note on the Y Combinator
242
+
Note that our "Hello world!" function to recursively compute the $n^{th}$ Fibonacci number [above](#starting-with-the-ghci-repl) was not at all efficient (in fact $O(2^n)$). We will now demonstrate a very idiomatic haskell construction for defining a lazy sequence of Fibonacci numbers that is linear time in the number of fibs required. In the following definition for `lazyFibs`, `zipWith` is a function which uses the specified function (in this case `(+)`) to pair the heads of two given lists. In this case, we are zipping over recursive references to `lazyFibs` and `tail lazyFibs`.
243
+
244
+
```haskell
245
+
lazyFibs =1:1:zipWith(+) lazyFibs (tail lazyFibs)
246
+
```
247
+
We can then create as much of the list as we need:
248
+
```haskell
249
+
take10 lazyFibs
250
+
[1,1,2,3,5,8,13,21,34,55]
251
+
```
252
+
This is only possible because Haskell's lazy evaluation only forces evaluation of the heads of the lists as necessary, e.g. to output the result of `take 10`.
The Haskell way of defining Lambda (anonymous) functions is heavily inspired by [Lambda Calculus](/lambdacalculus/), but also looks a bit reminiscent of the JavaScript arrow syntax:
245
259
@@ -269,7 +283,7 @@ y = \f -> (\x -> f (unsafeCoerce x x)) (\x -> f (unsafeCoerce x x))
269
283
main =putStrLn$ y ("circular reasoning works because "++)
270
284
```
271
285
272
-
---
286
+
</div>
273
287
274
288
## Functional Programming in Haskell versus JavaScript
275
289
@@ -382,8 +396,7 @@ sort (pivot:rest) = let
382
396
Note that where is only available in function declarations, not inside expressions and therefore is not available in a lambda. However, `let`-`in` is part of the expression, and therefore available inside a lambda function. A silly example would be: `\i -> let f x = 2*x in f i`, which could also be spread across lines, but be careful to get the correct indentation.
383
397
384
398
<divclass="cheatsheet"markdown="1">
385
-
386
-
## Conditional Code Constructs Cheatsheet
399
+
**Conditional Code Constructs Cheatsheet**
387
400
388
401
### Pattern matching
389
402
@@ -438,21 +451,6 @@ fibs n = case n of
438
451
439
452
</div>
440
453
441
-
## A lazy infinite sequence
442
-
443
-
Let's briefly revisit fibonacci numbers and demonstrate a very idiomatic haskell construction for defining a lazy sequence. In the following definition for `lazyFibs`, `zipWith` is a function which uses the specified function (in this case `(+)`) to pair the heads of two given lists. In this case, we are zipping over recursive references to `lazyFibs` and `tail lazyFibs`.
444
-
445
-
```haskell
446
-
lazyFibs =1:1:zipWith(+) lazyFibs (tail lazyFibs)
447
-
```
448
-
We can then create as much of the list as we need:
449
-
```haskell
450
-
take10 lazyFibs
451
-
[1,1,2,3,5,8,13,21,34,55]
452
-
```
453
-
This is only possible because Haskell's lazy evaluation only forces evaluation of the heads of the lists as necessary, e.g. to output the result of `take 10`.
*GHCi REPL*: The interactive Read-Eval-Print Loop for GHC, the Glasgow Haskell Compiler, allowing users to test Haskell programs and expressions interactively.
0 commit comments