Skip to content

Commit 7f38bc5

Browse files
Update tut01 for B232
1 parent 7fdf3e5 commit 7f38bc5

1 file changed

Lines changed: 57 additions & 73 deletions

File tree

tutorials/01_fp-env.md

Lines changed: 57 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ Principles [[jdegoes](https://twitter.com/jdegoes/status/974045822424776704?s=09
5555
* [Cabal] = system for building and packaging.
5656
* [Stack] = managing Haskell projects, works with [Cabal] for you.
5757

58-
:point_right: Please, install these (or check if installed already) - you can follow instruction on official websites one by one or (better) install [Haskell Platform], which includes all of those and also most common packages.
58+
:point_right: Please, install these (or check if installed already) - you can follow instruction on official websites one by one or (recommended and better) install [GHCup], which includes all of those and also most common packages.
5959

6060
### Editors and IDEs
6161

@@ -66,21 +66,6 @@ There are several editors you may use for writing Haskell programs, most probabl
6666
* [Atom with plugins](https://atom-haskell.github.io/overview/)
6767
* [Visual Studio Code with plugins](https://medium.com/@dogwith1eye/setting-up-haskell-in-vs-code-with-stack-and-the-ide-engine-81d49eda3ecf)
6868

69-
Most probably you will need following stuff:
70-
71-
* [ghc-mod] = connector to [GHC] API for various stuff, alternatively you can use [HIE](https://github.com/haskell/haskell-ide-engine)
72-
* [hlint] = source code suggestion
73-
* [hindent] = indenter, pretty print
74-
* [stylish-haskell] = code prettifier ("good style")
75-
76-
Install those with [Cabal] (by default it will install just for you to your profile, ensure that you have `~/.cabal/bin` in your `PATH`) or with [Stack]. The installation might take a while - it has a lot of dependencies and needs to build them from Haskell source code. If you want to install something with [Cabal] to all users, use `--global` flag.
77-
78-
```console
79-
$ cabal update
80-
$ cabal install hlint stylish-haskell hindent ghc-mod
81-
$ stack install hlint stylish-haskell hindent ghc-mod
82-
```
83-
8469
### Sites for searching
8570

8671
* [Hoogle] = "Google" for Haskell world
@@ -106,19 +91,19 @@ Now you should have [GHC] installed from package or via Stack (and others as wel
10691

10792
```console
10893
% ghc --version
109-
The Glorious Glasgow Haskell Compilation System, version 8.0.2
94+
The Glorious Glasgow Haskell Compilation System, version 9.4.8
11095
% stack exec -- ghc --version
111-
The Glorious Glasgow Haskell Compilation System, version 8.0.2
96+
The Glorious Glasgow Haskell Compilation System, version 9.4.5
11297
```
11398

11499
First, let's try the interactive environment and evaluate some basic expression in Haskell for the first time.
115100

116101
```
117102
% ghci
118-
GHCi, version 8.0.2: http://www.haskell.org/ghc/ :? for help
119-
Prelude> "Hello, world!"
103+
GHCi, version 9.4.8: http://www.haskell.org/ghc/ :? for help
104+
ghci> "Hello, world!"
120105
"Hello, world!"
121-
Prelude> putStrLn "Hello, world!"
106+
ghci> putStrLn "Hello, world!"
122107
Hello, world!
123108
```
124109

@@ -129,43 +114,43 @@ In prompt you see (by default) imported modules, in this case just `Prelude` - t
129114
In Haskell you can use math operators as you are used to.
130115

131116
```
132-
Prelude> 5 + 5
117+
ghci> 5 + 5
133118
10
134-
Prelude> 5 + 5 * 3
119+
ghci> 5 + 5 * 3
135120
20
136-
Prelude> (5 + 5) * 3
121+
ghci> (5 + 5) * 3
137122
30
138-
Prelude> 2 ^ 8
123+
ghci> 2 ^ 8
139124
256
140-
Prelude> 2 / 3
125+
ghci> 2 / 3
141126
0.6666666666666666
142127
```
143128

144129
Integer division and modulo are done by functions. You can call functions in prefix notation (no brackets and no commas):
145130

146131
```
147-
Prelude> div 7 2
132+
ghci> div 7 2
148133
3
149-
Prelude> mod 7 2
134+
ghci> mod 7 2
150135
1
151136
```
152137

153138
Same goes for logic and comparison (you might be used to `!=` or `<>` for not-equal, but `!` and `<>` are used for something else in Haskell we will find out during the course):
154139

155140
```
156-
Prelude> 5 > 7
141+
ghci> 5 > 7
157142
False
158-
Prelude> 5 == 7
143+
ghci> 5 == 7
159144
False
160-
Prelude> 5 /= 7
145+
ghci> 5 /= 7
161146
True
162-
Prelude> not (5 /= 7)
147+
ghci> not (5 /= 7)
163148
False
164-
Prelude> False || True
149+
ghci> False || True
165150
True
166-
Prelude> False && True
151+
ghci> False && True
167152
False
168-
Prelude> not False && True
153+
ghci> not False && True
169154
True
170155
```
171156

@@ -174,20 +159,20 @@ True
174159
A very useful thing in GHCi is that you can check the type of an expression.
175160

176161
```
177-
Prelude> :type 2 ^ 8
162+
ghci> :type 2 ^ 8
178163
2 ^ 8 :: Num a => a
179-
Prelude> :type 2 / 3
164+
ghci> :type 2 / 3
180165
2 / 3 :: Fractional a => a
181166
```
182167

183168
The double semicolon `::` means "is of type" and you can use it for explicitly stating the type of your expressions. But this is not typecasting as you might know, you must conform the restriction, in this case, `Fractional a` (typeclasses will be covered deeply in next lessons).
184169

185170
```
186-
Prelude> (2 / 3) :: Double
171+
ghci> (2 / 3) :: Double
187172
0.6666666666666666
188-
Prelude> (2 / 3) :: Float
173+
ghci> (2 / 3) :: Float
189174
0.6666667
190-
Prelude> (2 / 3) :: Int
175+
ghci> (2 / 3) :: Int
191176
192177
<interactive>:2:2: error:
193178
• No instance for (Fractional Int) arising from a use of ‘/’
@@ -200,11 +185,11 @@ You can see that error message exactly tells us what is wrong! `Int` is not an i
200185
If you need to change type, find a suitable function. Some of them are in `Prelude`: `toInteger`, `fromInteger`, `toRational`, etc. Another quite important is `show` for showing anything as `String`. How these work will be covered later on in more detail as we get to typeclasses and polymorphism!
201186

202187
```
203-
Prelude> :t toInteger (7::Int)
188+
ghci> :t toInteger (7::Int)
204189
toInteger (7::Int) :: Integer
205-
Prelude> show (2/3)
190+
ghci> show (2/3)
206191
"0.6666666666666666"
207-
Prelude> toRational (2/16)
192+
ghci> toRational (2/16)
208193
1 % 8
209194
```
210195

@@ -213,13 +198,13 @@ Similarly you can do such thing with functions, because we are in functional lan
213198
The type signature is very math-like... Instance (type) of `Num` is for example `Integer` and you know functions from math which have type `Integer -> Integer` (domain and co-domain).
214199

215200
```
216-
Prelude> :type abs
201+
ghci> :type abs
217202
abs :: Num a => a -> a
218-
Prelude> abs (-5)
203+
ghci> abs (-5)
219204
5
220-
Prelude> abs (-10.65)
205+
ghci> abs (-10.65)
221206
10.65
222-
Prelude> abs "z"
207+
ghci> abs "z"
223208
224209
<interactive>:26:1: error:
225210
• No instance for (Num [Char]) arising from a use of ‘abs’
@@ -230,20 +215,20 @@ Prelude> abs "z"
230215
The operators are functions as well - Haskell is functional language. All you need to do is put it in brackets. Plus takes two numbers and returns a number. You can then use `(+)` as a function in prefix notation and not infix.
231216

232217
```
233-
Prelude> :type (+)
218+
ghci> :type (+)
234219
(+) :: Num a => a -> a -> a
235-
Prelude> (+) 5 4
220+
ghci> (+) 5 4
236221
9
237222
```
238223

239224
On the other hand you might want to use some functions in infix to improve readability and you need `` ` `` for that.
240225

241226
```
242-
Prelude> :t div
227+
ghci> :t div
243228
div :: Integral a => a -> a -> a
244-
Prelude> 5 `div` 3
229+
ghci> 5 `div` 3
245230
1
246-
Prelude> 5 `mod` 3
231+
ghci> 5 `mod` 3
247232
2
248233
```
249234

@@ -252,21 +237,21 @@ Prelude> 5 `mod` 3
252237
In GHCi you can name an expression with `let` and assignment.
253238

254239
```
255-
Prelude> let x = 5
256-
Prelude> :type x
240+
ghci> let x = 5
241+
ghci> :type x
257242
x :: Num t => t
258-
Prelude> let x = 5 :: Integer
259-
Prelude> :type x
243+
ghci> let x = 5 :: Integer
244+
ghci> :type x
260245
x :: Integer
261246
```
262247

263248
You can create functions as well. Notice that the type is automatically inferred. It happens every time when possible and you don't explicitly state the type.
264249

265250
```
266-
Prelude> let myFunc x y = 2 * x + y
267-
Prelude> :t myFunc
251+
ghci> let myFunc x y = 2 * x + y
252+
ghci> :t myFunc
268253
myFunc :: Num a => a -> a -> a
269-
Prelude> myFunc 5 3
254+
ghci> myFunc 5 3
270255
13
271256
```
272257

@@ -297,7 +282,7 @@ isTriangle a b c = (a + b > c) && (a + c > b) && (b + c > a)
297282
Now we can load it with `:load` to GHCi:
298283

299284
```
300-
Prelude> :load FPCourse/files/01_test_haskell.hs
285+
ghci> :load FPCourse/files/01_test_haskell.hs
301286
[1 of 1] Compiling Main ( 01_test_haskell.hs, interpreted )
302287
Ok, modules loaded: Main.
303288
```
@@ -423,7 +408,7 @@ Let's do the *Hello, world!* app with [Stack]. First, verify that you have it in
423408

424409
```console
425410
% stack --version
426-
Version 1.9.3, Git revision 40cf7b37526b86d1676da82167ea8758a854953b (6211 commits) x86_64 hpack-0.31.1
411+
Version 2.13.1, Git revision 8102bb8afce90fc954f48efae38b87f37cabc988 (9949 commits) aarch64 hpack-0.36.0
427412
```
428413

429414
Then you can create a new project with default template:
@@ -459,10 +444,10 @@ Using cabal packages:
459444

460445
Selecting the best among 15 snapshots...
461446

462-
* Matches lts-13.8
447+
* Matches lts-21.25
463448

464-
Selected resolver: lts-13.8
465-
Initialising configuration using resolver: lts-13.8
449+
Selected resolver: lts-21.25
450+
Initialising configuration using resolver: lts-21.25
466451
Total number of user packages considered: 1
467452
Writing configuration to file: HelloWorld/stack.yaml
468453
All done.
@@ -497,7 +482,7 @@ Now you don't use GHC directly, but call it via `stack build`:
497482

498483
```console
499484
% stack build
500-
No compiler found, expected minor version match with ghc-8.0.2 (x86_64) (based on resolver setting in /home/user/.stack/global-project/stack.yaml).
485+
No compiler found, expected minor version match with ghc-9.4.8 (x86_64) (based on resolver setting in /home/user/.stack/global-project/stack.yaml).
501486
To install the correct GHC into /home/user/.stack/programs/x86_64-linux/, try running "stack setup" or use the "--install-ghc" flag. To use your system GHC installation, run "stack config set system-ghc --global true", or use the "--system-ghc" flag.
502487
```
503488

@@ -507,7 +492,7 @@ As you see `stack` doesn't want to use system-wide installation of `ghc` but loc
507492
% stack setup
508493
Preparing to install GHC to an isolated location.
509494
This will not interfere with any system-level installation.
510-
Downloaded ghc-8.0.2.
495+
Downloaded ghc-9.4.8.
511496
Installed GHC.
512497
stack will use a sandboxed GHC it installed
513498
For more information on paths, see 'stack path' and 'stack exec env'
@@ -521,10 +506,10 @@ Using cabal packages:
521506

522507
Selecting the best among 11 snapshots...
523508

524-
* Matches lts-13.8
509+
* Matches lts-21.25
525510

526-
Selected resolver: lts-13.8
527-
Initialising configuration using resolver: lts-9.11
511+
Selected resolver: lts-21.25
512+
Initialising configuration using resolver: lts-21.25
528513
Total number of user packages considered: 1
529514
Writing configuration to file: stack.yaml
530515
All done.
@@ -544,8 +529,8 @@ Building executable 'HelloWorld-exe' for HelloWorld-0.1.0.0..
544529
[2 of 2] Compiling Paths_HelloWorld ( .stack-work/dist/x86_64-linux-tinfo6/Cabal-2.4.0.1/build/HelloWorld-exe/autogen/Paths_HelloWorld.hs, .stack-work/dist/x86_64-linux-tinfo6/Cabal-2.4.0.1/build/HelloWorld-exe/HelloWorld-exe-tmp/Paths_HelloWorld.o )
545530
Linking .stack-work/dist/x86_64-linux-tinfo6/Cabal-2.4.0.1/build/HelloWorld-exe/HelloWorld-exe ...
546531
HelloWorld-0.1.0.0: copy/register
547-
Installing library in /home/user/Projects/MI-AFP/tests/HelloWorld/.stack-work/install/x86_64-linux-tinfo6/lts-13.8/8.6.3/lib/x86_64-linux-ghc-8.6.3/HelloWorld-0.1.0.0-8b39YCi0nmn4QsoDKix2j8
548-
Installing executable HelloWorld-exe in /home/user/Projects/MI-AFP/tests/HelloWorld/.stack-work/install/x86_64-linux-tinfo6/lts-13.8/8.6.3/bin
532+
Installing library in /home/user/Projects/MI-AFP/tests/HelloWorld/.stack-work/install/x86_64-linux-tinfo6/lts-21.25/9.4.8/lib/x86_64-linux-ghc-8.6.3/HelloWorld-0.1.0.0-8b39YCi0nmn4QsoDKix2j8
533+
Installing executable HelloWorld-exe in /home/user/Projects/MI-AFP/tests/HelloWorld/.stack-work/install/x86_64-linux-tinfo6/lts-21.25/9.4.8/bin
549534
Registering library for HelloWorld-0.1.0.0..
550535
stack build 6.16s user 0.94s system 96% cpu 7.329 total
551536
```
@@ -647,13 +632,12 @@ For your first assignment, visit [MI-AFP/hw01](https://github.com/MI-AFP/hw01).
647632
[Cabal]: https://www.haskell.org/cabal/
648633
[Elm]: http://elm-lang.org
649634
[GHC]: https://www.haskell.org/ghc/
650-
[ghc-mod]: https://github.com/DanielG/ghc-mod
651635
[GHCJS]: https://github.com/ghcjs/ghcjs
636+
[GHCup]: https://www.haskell.org/ghcup/
652637
[GitHub]: https://github.com
653638
[Hackage]: https://hackage.haskell.org
654639
[Haskell]: https://www.haskell.org
655640
[Haskell 2010]: https://www.haskell.org/onlinereport/haskell2010/
656-
[Haskell Platform]: https://www.haskell.org/platform/
657641
[Haste]: https://haste-lang.org
658642
[hindent]: https://github.com/commercialhaskell/hindent
659643
[hlint]: https://hackage.haskell.org/package/hlint

0 commit comments

Comments
 (0)