-
Notifications
You must be signed in to change notification settings - Fork 37
/
Lect01.lhs
164 lines (117 loc) · 4.8 KB
/
Lect01.lhs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
% CS 340: Programming Paradigms and Patterns
% Lect 01 - Introduction to Haskell
% Michael Lee
> module Lect01 where
> import Data.List
Introduction to Haskell
=======================
Agenda:
- working with literate source files
- general development workflow and tools
- notable (& maybe surprising) language features
- indentation and layout rules
Literate Haskell
----------------
Regular Haskell source code filenames end in ".hs" --- all your assignments
will use this extension --- but they can also end in ".lhs", which denotes a
"literate" Haskell source file. In a literate source file, all text defaults
to being a comment; lines of source code must start with the ">" character,
and must also be separated from other text by at least one empty line.
All lecture notes will be provided as literate source files. Here's what code
would look like in a literate source file:
> welcome = "Welcome to CS 340!"
You can also surround code with begin/end markers, like this:
\begin{code}
courseName = "Programming Paradigms and Patterns"
\end{code}
Development workflow and tools
------------------------------
You'll need to switch frequently between multiple tools and platforms to
do your work in this class. They include:
- Git, a version control system
- GitHub, a Git hosting service
- GHCUp, an installer for Haskell development tools
- GHC, the Glasgow Haskell Compiler
- a source code editor with Haskell support --- I recommend Visual Studio Code
with the Haskelly plugin unless you strongly prefer a different editor and
are willing to figure out how to set it up on your own
Notable (& maybe surprising) language features
----------------------------------------------
1. Strong static typing: Every expression or variable has a type associated with
it that doesn't change, and is rigidly enforced by the
compiler. Haskel programs are type-safe; i.e., there
will never be run-time type related errors!
2. Type inference: The compiler can figure out the types of many things, so that
we don't have to expliclty label them.
> -- use the :t GHCi command to get the type of each of the below
>
> mysteryVar1 = 123 `mod` 8
>
> mysteryVar2 = words "hello how are you?"
>
> mysteryFn1 = (^2)
>
> mysteryFn2 = length . words
>
> mysteryFn3 f s = [(abs $ f $ length w, w) | w <- words s]
3. Purely functional: Once variables are bound to values they cannot be changed
(i.e., variables are immutable).
> boundVar = 10
> -- boundVar = 20 -- error!
4. Lazy evaluation: Expressions (e.g., function calls) are not evaluated until
their results are strictly needed. Unevaluated computations,
called "thunks", are maintained in a graph.
> possiblyTragic c = let e = error "Eeek!"
> u = undefined
> in case c of 'e' -> e
> 'u' -> u
> otherwise -> "safe"
>
> safeDiv x y = let q = x `div` y
> in if y == 0
> then 0
> else q
5 . Order-independence: The order bindings appear in code doesn't matter.
> w = x + 2
> x = w - 5
>
> evenN 0 = True
> evenN n = oddN (n-1)
>
> oddN 0 = False
> oddN n = evenN (n-1)
6. Concise
- Small language with few keywords:
case class data deriving do else if
import in infix infixl infixr instance
let module newtype of then type where
- Declarative vs. Imperative style!
> palindromes = sortOn snd
> . map (\w -> (w,length w))
> . filter (\s -> reverse s == s)
> . words
Indentation & Layout rules
--------------------------
Haskell supports the use of semicolons and curly braces for delineating
and separating blocks of code, but they are rarely used. Instead, we prefer
to take advantage of *layout rules* that use indentation to group and separate
code.
The "golden rule" for Haskell indentation is:
Code which is part of some expression should be indented further in
than the beginning of that expression.
In addition, all expressions that belong to the same group must be left-aligned
to the same column. The "do", "let", "where", and "of" keywords indicate the
start of group.
> doGuessing num = do
> putStrLn "Enter your guess:"
> guess <- getLine
> case compare (read guess) num of
> LT -> do putStrLn "Too low!"
> doGuessing num
> GT -> do putStrLn "Too high!"
> doGuessing num
> EQ -> putStrLn "You Win!"
Read the [Haskell Wikibook](https://en.wikibooks.org/wiki/Haskell/Indentation)
for a briefer on the layout rule, and the
[Haskell language report](https://www.haskell.org/onlinereport/haskell2010/haskellch2.html#x7-210002.7)
for all the gory details.