git.iko.soy/Haskell-HSE/haskell-lectures-2024
on main help sign in
fix lecture files
655eafeTurtlePU
.ghcinew file+2
@@ -0,0 +1,2 @@
1+:set -package markdown-unlit
2+:set -pgmL markdown-unlit
1.Intro.lhsmode 100644 → 120000+1−784
@@ -1,784 +0,0 @@
1−* Haskell 2024 - Intro
2−
3−** What is Haskell?
4−
5−As written in Wikipedia:
6−
7−Haskell (/ˈhæskəl/) is a general-purpose, statically-typed, purely functional
8−programming language with type inference and lazy evaluation. Designed for
9−teaching, research, and industrial applications, Haskell has pioneered a number
10−of programming language features such as type classes, which enable type-safe
11−operator overloading, and monadic input/output (IO). It is named after logician
12−Haskell Curry. Haskell's main implementation is the Glasgow Haskell Compiler
13−(GHC).
14−
15−** Where is Haskell used?
16−
17−Haskell is used in academia and in industry:
18−
19− * The proof assistant Agda is written in Haskell.
20− * Darcs is a revision control system written in Haskell, with several
21− innovative features, such as more precise control of patches to apply.
22− * GHC is also often a testbed for advanced functional programming features and
23− optimizations in other programming languages.
24− * Git-annex is a tool to manage (big) data files under Git version control. It
25− also provides a distributed file synchronization system
26− (git-annex assistant).
27− * Linspire Linux chose Haskell for system tools development.
28− * Pandoc is a tool to convert one markup format into another.
29− * Pugs is a compiler and interpreter for the Raku programming language
30− (formerly Perl 6).
31− * TidalCycles is a domain special language for live coding musical patterns,
32− embedded in Haskell.
33− * Xmonad is a window manager for the X Window System written fully in Haskell.
34− * GarganText is a collaborative tool to map through semantic analysis texts on
35− any web browser, written fully in Haskell and PureScript, which is used for
36− instance in the research community to draw up state-of-the-art reports and
37− roadmaps.
38−
39−*** Industry
40−
41− * Bluespec SystemVerilog (BSV) is a language for semiconductor design that is
42− an extension of Haskell. Also, Bluespec, Inc.'s tools are implemented in
43− Haskell. Note this is an example of a DSL embedded into Haskell.
44− * Cryptol, a language and toolchain for developing and verifying cryptography
45− algorithms, is implemented in Haskell.
46− * Facebook implements its anti-spam programs in Haskell, maintaining the
47− underlying data access library as open-source software.
48− * The Cardano blockchain platform is implemented in Haskell.
49− * GitHub implemented Semantic, an open-source library for analysis, diffing,
50− and interpretation of untrusted source code, in Haskell.
51− * Standard Chartered's financial modelling language Mu is syntactic Haskell
52− running on a strict runtime.
53− * seL4, the first formally verified microkernel, used Haskell as a prototyping
54− language for the OS developer. At the same time, the Haskell code defined an
55− executable specification with which to reason, for automatic translation by
56− the theorem-proving tool. The Haskell code thus served as an intermediate
57− prototype before final C refinement.
58− * Target stores' supply chain optimization software is written in Haskell.
59− * Co–Star
60−
61−*** Some more examples from Serokell
62−
63− * Hasura is an open-source GraphQL engine that gives you instant access to a
64− GraphQL API for your data. In the GitHub repository of Hasura, Haskell is
65− the most used language, followed by languages like TypeScript, JavaScript,
66− Python, and Go. At the start of 2022, Hasura raised \$100 million.
67− * Microsoft uses Haskell in Bond, a cross-platform framework for working with
68− schematized data. The Haskell part of Bond is mainly gbc, a command-line
69− code generation tool that can generate C++ and C# code using Bond. For a
70− long time, Microsoft Research also significantly supported the Glasgow
71− Haskell Compiler (GHC) by employing Simon Peyton Jones to work on it.
72− * Tesla has been regularly hiring Haskell engineers and interns for some years
73− already. There isn’t a lot of information out there about the exact
74− specifics of their work. According to a comment in a job post made on
75− Reddit, they use Haskell to generate C code that is then compiled into
76− vehicle firmware.
77− * Freckle is an online learning platform that adjusts to the skills of
78− students. They use Haskell for all of their backend services and most of
79− their tooling.
80− * Galois is a company that specializes in the research and development of
81− trustworthy software systems for fields where failure is unacceptable.
82− One of their most interesting projects is Copilot, a stream-based DSL for
83− writing and monitoring embedded C programs.
84− * Serokell uses Haskell to great success for most of their day-to-day software
85− development projects. They have used it to build the settlement layer of the
86− Cardano blockchain, programming languages for the Tezos blockchain,
87− cryptocurrency exchanges, a multi-currency wallet with its own DSL and more.
88−
89−** What are the benefits of using Haskell?
90−
91−Companies above list three things as the most significant benefits of Haskell:
92−
93− 1. Expressive type system.
94− 2. Strong correctness guarantees.
95− 3. Easy refactoring.
96−
97−In addition, while Haskell is a great programming language for everyday
98−purposes, we can separate two popular use cases:
99−
100− 1. Complex systems where strong guarantees are required (such as blockchains
101− like Cardano and fintech projects like Klarna).
102− 2. The second is compilers and DSLs. On our list, the examples for this use
103− case are projects like Bond, Semantic, Copilot.
104−
105−Both of these use cases heavily benefit from the strengths of Haskell and manage
106−to dodge most of its cons. They can rightfully be called the “killer apps” of
107−Haskell.
108−
109−If you are considering a project in these two areas, it’s hard to go wrong with
110−picking Haskell.
111−
112−* Basic language constructs
113−
114−This file is actually a /literate Haskell/ file with extension @.lhs@ where
115−every piece of code is indented with @>@ like this:
116−
117−> a = 5
118−
119−Normal code is written without indent and is split into /modules/ each in their
120−own file with extension @.hs@. To write a comment, a double dash is used:
121−
122−> -- This is a comment inside code block in a literate Haskell file.
123−> {- And this is a multiline comment.
124−> A little useless, isn't it? -}
125−
126−** Primitive Datatypes and Operators
127−
128−Of course, Haskell has numbers, booleans, characters, strings and whatnot:
129−
130−> b = a + 1 -- 6
131−> c = 3 - 2 -- 1
132−> d = 10 * 2 -- 20
133−> e = 35 / 5
134−
135−However, if you load this file into a Haskell interpreter called @ghci@, you'll
136−see the following:
137−
138−@
139−~/haskell-lectures-2024 $ ghci 1.Intro.lhs
140−GHCi, version 9.4.8: https://www.haskell.org/ghc/ :? for help
141−[1 of 2] Compiling Main ( 1.Intro.lhs, interpreted )
142−Ok, one module loaded.
143−ghci> e
144−7.0
145−@
146−
147−So division is not integer division by default. Actual integer division:
148−
149−> this_is_eight = 35 `div` 4
150−
151−Boolean operations:
152−
153−> f = not True
154−> g = not False
155−> h = True && False
156−> i = True || False
157−> j = 1 == 1
158−> k = 1 /= 1
159−> l = 1 < 10
160−
161−In the above examples, @not@ is a function that takes one value. Haskell doesn't
162−need parentheses for function calls --- all the arguments are just listed after
163−the function. So the general pattern is: @func arg1 arg2 arg3...@ See the
164−section on functions for information on how to write your own.
165−
166−Strings and characters:
167−
168−> m = "This is a string."
169−> n = 'a'
170−> -- o = 'You cant use single quotes for strings.' -- error!
171−
172−Strings can be concatenated:
173−
174−> p = "Hello " ++ "world!"
175−
176−A string is a list of characters:
177−
178−> q = ['H', 'e', 'l', 'l', 'o']
179−
180−Lists can be indexed with the @!!@ operator followed by an index
181−
182−> s = "This is a string" !! 0
183−
184−** Lists
185−
186−Every element in a list must have the same type. These two lists are equal:
187−
188−> l1 = [1, 2, 3, 4, 5]
189−> l2 = [1..5]
190−
191−Ranges are versatile.
192−
193−> charRange = ['A'..'F'] -- "ABCDEF"
194−> orderingRange = [LT .. GT] -- [LT, EQ, GT]
195−
196−You can create a step in a range.
197−
198−> evenStep = [0,2..10] -- [0, 2, 4, 6, 8, 10]
199−> notStepped = [5..1] -- [] (Haskell defaults to incrementing)
200−> decrementStep = [5,4..1] -- [5, 4, 3, 2, 1]
201−
202−Indexing into a list
203−
204−> thirdGlyph = [1..10] !! 3 -- 4 (zero-based indexing)
205−
206−You can also have infinite lists in Haskell!
207−
208−> nats = [1..] -- a list of all the natural numbers
209−
210−Infinite lists work because Haskell has "lazy evaluation". This means that
211−Haskell only evaluates things when it needs to. So you can ask for the 1000th
212−element of your list and Haskell will give it to you:
213−
214−> someNat = [1..] !! 999 -- 1000
215−
216−And now Haskell has evaluated elements 1 - 1000 of this list... but the rest of
217−the elements of this "infinite" list don't exist yet! Haskell won't actually
218−evaluate them until it needs to.
219−
220−Joining two lists:
221−
222−> joinedLists = [1..5] ++ [6..10]
223−
224−Adding to the head of a list:
225−
226−> headCat = 0:[1..5] -- [0, 1, 2, 3, 4, 5]
227−
228−More list operations
229−
230−> someHead = head [1..5] -- 1
231−> someTail = tail [1..5] -- [2, 3, 4, 5]
232−> someInit = init [1..5] -- [1, 2, 3, 4]
233−> someLast = last [1..5] -- 5
234−
235−Actually, you can lookup them on [hoogle](https://hoogle.haskell.org/) or, even
236−better, find them there by their type signature!
237−
238−List comprehensions
239−
240−> comp = [x*2 | x <- [1..5]] -- [2, 4, 6, 8, 10]
241−
242−With a conditional
243−
244−> compCond = [x*2 | x <- [1..5], x*2 > 4] -- [6, 8, 10]
245−
246−With several iteratees
247−
248−> twoD = take 10 [x ^ 2 * y | x <- [1..], even x, x `mod` 3 == 0, y <- [1, -1]]
249−
250−** Tuples
251−
252−Every element in a tuple can be a different type, but a tuple has a fixed
253−length. A tuple:
254−
255−> tupleExample = ("haskell", 1)
256−
257−Accessing elements of a pair (i.e. a tuple of length 2)
258−
259−> someFst = fst ("haskell", 1) -- "haskell"
260−> someSnd = snd ("haskell", 1) -- 1
261−
262−Pair element accessing does not work on n-tuples (i.e. triple, quadruple, etc)
263−
264−> -- snd ("snd", "can't touch this", "da na na na") -- error! see function below
265−
266−** Functions
267−
268−A simple function that takes two variables
269−
270−> add a b = a + b
271−
272−Using the function
273−
274−> three = add 1 2 -- 3
275−
276−You can also put the function name between the two arguments with backticks:
277−
278−> alsoThree = 1 `add` 2 -- 3
279−
280−You can also define functions that have no letters! This lets you define your
281−own operators! Here's an operator that does integer division
282−
283−> (//) a b = a `div` b
284−> eight = 35 // 4 -- 8
285−
286−*** Guards
287−
288−An easy way to do branching in functions
289−
290−> fib x
291−> | x < 2 = 1
292−> | otherwise = fib (x - 1) + fib (x - 2)
293−
294−*** Pattern matching
295−
296−Pattern matching is similar. Here we have given three different equations that
297−define @fib'@. Haskell will automatically use the first equation whose left hand
298−side pattern matches the value.
299−
300−> fib' 1 = 1
301−> fib' 2 = 2
302−> fib' x = fib' (x - 1) + fib' (x - 2)
303−
304−*** Pattern matching on tuples
305−
306−> sndOfTriple (_, y, _) = y -- use a wild card (_) to bypass naming unused value
307−
308−*** Pattern matching on lists
309−
310−Here @x@ is the first element in the list, and @xs@ is the rest of the list. We
311−can write our own map function:
312−
313−> myMap func [] = []
314−> myMap func (x:xs) = func x:(myMap func xs)
315−
316−Anonymous functions are created with a backslash followed by all the arguments.
317−
318−> mapped = myMap (\x -> x + 2) [1..5] -- [3, 4, 5, 6, 7]
319−
320−*** Using fold (called @inject@ in some languages) with an anonymous function
321−
322−foldl1 means fold left, and use the first value in the list as the initial value
323−for the accumulator.
324−
325−> usingFold = foldl1 (\acc x -> acc + x) [1..5] -- 15
326−
327−*** Partial application
328−
329−If you don't pass in all the arguments to a function, it gets "partially
330−applied". That means it returns a function that takes the rest of the arguments.
331−
332−> foo = add 10 -- foo is now a function that takes a number and adds 10 to it
333−> fifteen = foo 5 -- 15
334−
335−Another way to write the same thing. It is called a "section":
336−
337−> foo' = (10 +)
338−> alsoFifteen = foo' 5 -- 15
339−
340−*** Function composition
341−
342−The operator @.@ chains functions together. For example, here foo is a function
343−that takes a value. It adds 10 to it, multiplies the result of that by 4, and
344−then returns the final value.
345−
346−> foo'' = (4 *) . (10 +)
347−> sixty = foo'' 5 -- 4*(10+5) = 60
348−
349−*** Fixing precedence
350−
351−Haskell has an operator called @$@. This operator applies a function to a given
352−parameter. In contrast to standard function application, which has highest
353−possible priority of 10 and is left-associative, the @$@ operator has priority
354−of 0 and is right-associative. Such a low priority means that the expression on
355−its right is applied as a parameter to the function on its left.
356−
357−Before:
358−
359−> evenSeven = even (fib 7) -- false
360−
361−Equivalently:
362−
363−> evenSeven' = even $ fib 7 -- false
364−
365−Composing functions:
366−
367−> evenSeven'' = even . fib $ 7 -- false
368−
369−** Type signatures
370−
371−Haskell has a very strong type system, and every valid expression has a type.
372−Some basic types:
373−
374−> five = 5 :: Integer
375−> hello = "hello" :: String
376−> truth = True :: Bool
377−
378−Functions have types too. @not@ takes a boolean and returns a boolean:
379−
380−> not' = not :: Bool -> Bool
381−
382−Here's a function that takes two arguments:
383−
384−> add' = add :: Integer -> Integer -> Integer
385−
386−When you define a value, it's good practice to write its type above it:
387−
388−> double :: Integer -> Integer
389−> double x = x * 2
390−
391−*** Typed holes
392−
393−Haskell's type system allows one to use "typed holes" -- you can replace an
394−expression with an underscore and a compiler would tell you what is the expected
395−type of a missing expression:
396−
397−> -- double' x = _ * 2 :: Integer
398−
399−** Control Flow and If Expressions
400−
401−if-expressions
402−
403−> haskell = if 1 == 1 then "awesome" else "awful" -- haskell = "awesome"
404−
405−if-expressions can be on multiple lines too, indentation is important
406−
407−> haskell' = if 1 == 1
408−> then "awesome"
409−> else "awful"
410−
411−Case expressions: Here's how you could parse command line arguments
412−
413−> parseArgs args =
414−> case args of
415−> "help" -> printHelp
416−> "start" -> startProgram
417−> _ -> putStrLn "bad args"
418−>
419−> printHelp = undefined -- see Hoogle to learn what this is
420−> startProgram = undefined
421−
422−Haskell doesn't have loops; it uses recursion instead. map applies a function
423−over every element in a list
424−
425−> someEvens = map (*2) [1..5] -- [2, 4, 6, 8, 10]
426−
427−You can make a for function using map
428−
429−> for array func = map func array
430−
431−And then use it
432−
433−> strings = for [0..5] $ \i -> show i
434−
435−We could've written that like this too:
436−
437−> strs = for [0..5] show
438−
439−You can use foldl or foldr to reduce a list: @foldl <fn> <initial value> <list>@
440−
441−> fortyThree = foldl (\x y -> 2*x + y) 4 [1,2,3] -- 43
442−
443−This is the same as (2 * (2 * (2 * 4 + 1) + 2) + 3)
444−
445−While foldl is left-handed, foldr is right-handed
446−
447−> sixteen = foldr (\x y -> 2*x + y) 4 [1,2,3] -- 16
448−
449−This is now the same as (2 * 1 + (2 * 2 + (2 * 3 + 4)))
450−
451−** Data Types
452−
453−A data type is declared with a 'type constructor' on the left and one or more
454−'data constructors' on the right, separated by the pipe | symbol. This is a
455−sum/union type. Each data constructor is a (possibly nullary) function that
456−creates an object of the type named by the type constructor.
457−
458−This is essentially an enum
459−
460−> data Color = Red | Blue | Green -- enum in Rust
461−
462−Now you can use it in a function:
463−
464−> say :: Color -> String
465−> say Red = "You are Red!"
466−> say Blue = "You are Blue!"
467−> say Green = "You are Green!"
468−
469−Note that the type constructor is used in the type signature and the data
470−constructors are used in the body of the function. Data constructors are
471−primarily pattern-matched against.
472−
473−This next one is a traditional container type holding two fields. In a type
474−declaration, data constructors take types as parameters. Data constructors can
475−have the same name as type constructors: this is common where the type only has
476−a single data constructor, although here we do not do this to reduce confusion
477−for newcomers.
478−
479−> data Point = Cartesian Float Float
480−
481−This can be used in a function like:
482−
483−> distance :: Point -> Point -> Float
484−> distance (Cartesian x y) (Cartesian x' y') = sqrt $ dx + dy
485−> where dx = (x - x') ** 2
486−> dy = (y - y') ** 2
487−
488−Types can have multiple data constructors with arguments, too
489−
490−> data Name = Mononym String
491−> | FirstLastName String String
492−> | FullName String String String
493−
494−To make things clearer, we can use record syntax
495−
496−> data PointRecord = CartesianPoint2D { x :: Float, y :: Float }
497−> | PolarPoint2D { r :: Float, theta :: Float }
498−
499−> myPoint = CartesianPoint2D { x = 7.0, y = 10.0 }
500−
501−Using record syntax automatically creates accessor functions:
502−
503−> xOfMyPoint = x myPoint -- 7.0
504−
505−Record syntax also allows a simple form of update
506−
507−> myPoint' = myPoint { x = 9.0 } -- CartesianPoint2D { x = 9.0, y = 10.0 }
508−
509−Even if a type is defined with record syntax, it can be declared like a simple
510−data constructor. This is fine:
511−
512−> myPoint'' = CartesianPoint2D 3.3 4.0
513−
514−It's also useful to pattern match data constructors in `case` expressions
515−
516−> distanceFromOrigin x =
517−> case x of (CartesianPoint2D x y) -> sqrt $ x ** 2 + y ** 2
518−> (PolarPoint2D r _) -> r
519−
520−Your data types can have type parameters too:
521−
522−@
523−data Maybe a = Nothing | Just a
524−@
525−
526−These are all Maybes, but with different @a@s:
527−
528−> justHello = Just "hello" -- of type `Maybe String`
529−> justOne = Just 1 -- of type `Maybe Int`
530−> nothing = Nothing -- of type `Maybe a` for any `a`
531−
532−For convenience we can also create type synonyms with the @type@ keyword
533−
534−> type String' = [Char]
535−
536−Unlike @data@ types, type synonyms need no constructor, and can be used anywhere
537−a synonymous data type could be used. Say we have the following type synonyms
538−and items with the following type signatures
539−
540−> -- For demonstration purposes, these types have no constructors
541−> data Person
542−> data Circle
543−>
544−> -- Types in which we are interested
545−> type Weight = Float
546−> type Height = Float
547−> type Point2D = (Float, Float)
548−>
549−> getMyHeightAndWeight :: Person -> (Height, Weight)
550−> getMyHeightAndWeight = undefined
551−>
552−> findCenter :: Circle -> Point2D
553−> findCenter = undefined
554−>
555−> somePerson :: Person
556−> somePerson = undefined
557−>
558−> someCircle :: Circle
559−> someCircle = undefined
560−>
561−> distance2D :: Point2D -> Point2D -> Float
562−> distance2D = undefined
563−
564−The following would compile and run without issue, even though it does not make
565−sense semantically, because the type synonyms reduce to the same base types:
566−
567−> nonsense = distance2D (getMyHeightAndWeight somePerson) (findCenter someCircle)
568−
569−** Typeclasses
570−
571−Typeclasses are one way Haskell does polymorphism. They are similar to
572−interfaces in other languages: a typeclass defines a set of functions that must
573−work on any type that is in that typeclass.
574−
575−The
576−[Eq](https://hackage.haskell.org/package/base-4.19.0.0/docs/Prelude.html#t:Eq)
577−typeclass is for types whose instances can be tested for equality with one
578−another.
579−
580−@
581−class Eq a where
582− (==) :: a -> a -> Bool
583− (/=) :: a -> a -> Bool
584− x == y = not (x /= y)
585− x /= y = not (x == y)
586−@
587−
588−This defines a typeclass that requires two functions, @(==)@ and @(/=)@. It also
589−declares that one function can be declared in terms of another, so it is enough
590−that __either__ the @(==)@ function or the @(/=)@ is defined and the other will
591−be "filled in" based on the typeclass definition.
592−
593−To make a type a member of a type class, the @instance@ keyword is used
594−
595−> data TrafficLight = TLRed | TLYellow | TLGreen
596−>
597−> instance Eq TrafficLight where
598−> TLRed == TLRed = True
599−> TLGreen == TLGreen = True
600−> TLYellow == TLYellow = True
601−> _ == _ = False
602−
603−(Note that, while declaring @TrafficLight@ constructors, we had to name
604−constructors differently in order for them to not clash with @Color@
605−constructors we defined earlier. It is common to either prefix constructor
606−names with type name abbreviation or define types in different modules
607−altogether)
608−
609−Now we can use @(==)@ and @(/=)@ with TrafficLight objects:
610−
611−> canProceedThrough :: TrafficLight -> Bool
612−> canProceedThrough t = t /= TLRed
613−
614−You can NOT create an instance definition for a type synonym, though.
615−
616−Functions can be written to take typeclasses with type parameters, rather than
617−types, assuming that the function only relies on features of the typeclass:
618−
619−> isEqual :: Eq a => a -> a -> Bool
620−> isEqual x y = x == y
621−
622−Note that x and y MUST be the same type, as they are both defined as being of
623−type parameter @a@. A typeclass does not state that different types in the
624−typeclass can be mixed together. So @isEqual Red 2@ is invalid even though 2 is
625−an Int which is an instance of Eq, and Red is a TrafficLight which is also an
626−instance of Eq.
627−
628−Other common typeclasses are:
629−
630− * @Ord@ for types that can be ordered, allowing you to use >, <=, etc.
631− * @Read@ for types that can be created from a string representation
632− * @Show@ for types that can be converted to a string for display
633− * @Num@, @Real@, @Integral@, @Fractional@ for types that can do math
634− * @Enum@ for types that can be stepped through
635− * @Bounded@ for types with a maximum and minimum
636−
637−*** Literals
638−
639−We used character, string and list literals back from the very start. It is
640−simple to understand what they mean and how to use them. However, numeric
641−literals are not so simple. If we ask GHCi: "what is the type of 2?", we get:
642−
643−@
644−ghci> :t 2
645−2 :: Num a => a
646−@
647−
648−So numeric literals are actually polymorphic and do not have a concrete type.
649−Not that this is not the same as casts because the following is not allowed:
650−
651−> two = 2 :: Integer
652−> -- float = two * 0.5 -- would not pass the type check
653−
654−*** Deriving
655−
656−Haskell can automatically make types part of Eq, Ord, Read, Show, Enum and
657−Bounded with the @deriving@ keyword at the end of the type declaration
658−
659−> data PointDerives = Point Float Float deriving (Eq, Read, Show)
660−
661−In this case it is NOT necessary to create an @instance@ definition.
662−
663−** Haskell IO
664−
665−While IO can't be explained fully without explaining monads, it is not hard to
666−explain enough to get going.
667−
668−When a Haskell program is executed, @main@ is called. It must return a value of
669−type @IO a@ for some type @a@. For example:
670−
671−> main :: IO ()
672−> main = putStrLn $ "Hello, sky! " ++ (say Blue)
673−
674−(@putStrLn@ has type @String -> IO ()@)
675−
676−It is easiest to do IO if you can implement your program as a function from
677−String to String. The function
678−
679−> interact' = interact :: (String -> String) -> IO ()
680−
681−Inputs some text, runs a function on it, and prints out the output.
682−
683−> countLines :: String -> String
684−> countLines = show . length . lines
685−
686−> main' = interact countLines
687−
688−You can think of a value of type @IO ()@ as representing a sequence of actions
689−for the computer to do, much like a computer program written in an imperative
690−language. We can use the @do@ notation to chain actions together. For example:
691−
692−> sayHello :: IO ()
693−> sayHello = do
694−> putStrLn "What is your name?"
695−> name <- getLine -- this gets a line and gives it the name "name"
696−> putStrLn $ "Hello, " ++ name
697−
698−Exercise: write your own version of @interact@ that only reads one line of
699−input.
700−
701−The code in @sayHello@ will never be executed, however. The only action that
702−ever gets executed in the source file is the value of @main@. To run @sayHello@,
703−comment out the above definition of @main@, replace it with @main = sayHello@
704−and run @runhaskell <file name>@.
705−
706−Or, if you are running this module in GHCi, it can run any IO action on demand:
707−
708−@
709−ghci> sayHello
710−What is your name?
711−Pavel
712−Hello, Pavel
713−@
714−
715−Let's understand better how the function @getLine@ we just used works. Its type
716−is:
717−
718−> getLine' = getLine :: IO String
719−
720−You can think of a value of type @IO a@ as representing a computer program that
721−will generate a value of type @a@ when executed (in addition to anything else it
722−does). We can name and reuse this value using @<-@. We can also make our own
723−action of type @IO String@:
724−
725−> action :: IO String
726−> action = do
727−> putStrLn "This is a line. Duh"
728−> input1 <- getLine
729−> input2 <- getLine
730−> -- The type of the `do` statement is that of its last line.
731−> -- `return` is not a keyword, but merely a function
732−> return (input1 ++ "\n" ++ input2) -- return :: String -> IO String
733−
734−However, do-notation is not some compiler magic, this is just a syntactic sugar
735−over two operators called @>>@ and @>>=@. The action below is the same as the
736−action above:
737−
738−> action' = putStrLn "This is a line" >> (getLine >>= (\input1 ->
739−> getLine >>= (\input2 -> return (input1 ++ "\n" ++ input2))))
740−
741−We can use this just like we used @getLine@:
742−
743−> main'' = do
744−> putStrLn "I will echo two lines!"
745−> result <- action
746−> putStrLn result
747−> putStrLn "This was all, folks!"
748−
749−The type @IO@ is an example of a "monad". The way Haskell uses a monad to do IO
750−allows it to be a purely functional language. Any function that interacts with
751−the outside world (i.e. does IO) gets marked as @IO@ in its type signature. This
752−lets us reason about which functions are "pure" (don't interact with the outside
753−world or modify state) and which functions aren't.
754−
755−This is a powerful feature, because it's easy to run pure functions
756−concurrently; so, concurrency in Haskell is very easy.
757−
758−** Monads
759−
760−Actually, @do@-notation has wider application than only constructing IO values.
761−Is is applicable for every /monad/:
762−
763−@
764−ghci> :i Monad
765−type Monad :: (* -> *) -> Constraint
766−class Applicative m => Monad m where
767− (>>=) :: m a -> (a -> m b) -> m b
768− (>>) :: m a -> m b -> m b
769− return :: a -> m a
770−@
771−
772−In other words, @m@ is a monad if it allows to construct "pure" values of type
773−@m a@ from any value of type @a@ and if it allows to sequence actions of type
774−@m a@ and @m b@ and yield a result of type @m b@, where the second action either
775−can (@(>>=)@) or cannot (@(>>)@) depend on the result of the first action.
776−
777−This is discussed more in detail in the next lecture.
778−
779−* Sources & References
780−
781− * [Wikipedia page on Haskell](https://en.wikipedia.org/wiki/Haskell)
782− * [Serokell blog post on Haskell in industry](https://serokell.io/blog/top-software-written-in-haskell)
783− * [Memo for basic Haskell constructions](https://learnxinyminutes.com/docs/haskell/)
784− * [Hoogle, Haskell code search](https://hoogle.haskell.org/)
@@ -0,0 +1 @@
1+1.Intro.md
1.Intro.mdnew file+947
@@ -0,0 +1,947 @@
1+# Haskell 2024 - Intro
2+
3+## What is Haskell?
4+
5+As written in Wikipedia:
6+
7+Haskell (/ˈhæskəl/) is a general-purpose, statically-typed, purely functional
8+programming language with type inference and lazy evaluation. Designed for
9+teaching, research, and industrial applications, Haskell has pioneered a number
10+of programming language features such as type classes, which enable type-safe
11+operator overloading, and monadic input/output (IO). It is named after logician
12+Haskell Curry. Haskell's main implementation is the Glasgow Haskell Compiler
13+(GHC).
14+
15+## Where is Haskell used?
16+
17+Haskell is used in academia and in industry:
18+
19+* The proof assistant Agda is written in Haskell.
20+* Darcs is a revision control system written in Haskell, with several innovative
21+ features, such as more precise control of patches to apply.
22+* GHC is also often a testbed for advanced functional programming features and
23+ optimizations in other programming languages.
24+* Git-annex is a tool to manage (big) data files under Git version control. It
25+ also provides a distributed file synchronization system (git-annex assistant).
26+* Linspire Linux chose Haskell for system tools development.
27+* Pandoc is a tool to convert one markup format into another.
28+* Pugs is a compiler and interpreter for the Raku programming language
29+ (formerly Perl 6).
30+* TidalCycles is a domain special language for live coding musical patterns,
31+ embedded in Haskell.
32+* Xmonad is a window manager for the X Window System written fully in Haskell.
33+* GarganText is a collaborative tool to map through semantic analysis texts on
34+ any web browser, written fully in Haskell and PureScript, which is used for
35+ instance in the research community to draw up state-of-the-art reports and
36+ roadmaps.
37+
38+### Industry
39+
40+* Bluespec SystemVerilog (BSV) is a language for semiconductor design that is an
41+ extension of Haskell. Also, Bluespec, Inc.'s tools are implemented in Haskell.
42+ Note this is an example of a DSL embedded into Haskell.
43+* Cryptol, a language and toolchain for developing and verifying cryptography
44+ algorithms, is implemented in Haskell.
45+* Facebook implements its anti-spam programs in Haskell, maintaining the
46+ underlying data access library as open-source software.
47+* The Cardano blockchain platform is implemented in Haskell.
48+* GitHub implemented Semantic, an open-source library for analysis, diffing, and
49+ interpretation of untrusted source code, in Haskell.
50+* Standard Chartered's financial modelling language Mu is syntactic Haskell
51+ running on a strict runtime.
52+* seL4, the first formally verified microkernel, used Haskell as a prototyping
53+ language for the OS developer. At the same time, the Haskell code defined an
54+ executable specification with which to reason, for automatic translation by
55+ the theorem-proving tool. The Haskell code thus served as an intermediate
56+ prototype before final C refinement.
57+* Target stores' supply chain optimization software is written in Haskell.
58+* Co–Star
59+
60+### Some more examples from Serokell
61+
62+* Hasura is an open-source GraphQL engine that gives you instant access to a
63+ GraphQL API for your data. In the GitHub repository of Hasura, Haskell is the
64+ most used language, followed by languages like TypeScript, JavaScript, Python,
65+ and Go. At the start of 2022, Hasura raised \$100 million.
66+* Microsoft uses Haskell in Bond, a cross-platform framework for working with
67+ schematized data. The Haskell part of Bond is mainly gbc, a command-line code
68+ generation tool that can generate C++ and C# code using Bond. For a long time,
69+ Microsoft Research also significantly supported the Glasgow Haskell Compiler
70+ (GHC) by employing Simon Peyton Jones to work on it.
71+* Tesla has been regularly hiring Haskell engineers and interns for some years
72+ already. There isn’t a lot of information out there about the exact specifics
73+ of their work. According to a comment in a job post made on Reddit, they use
74+ Haskell to generate C code that is then compiled into vehicle firmware.
75+* Freckle is an online learning platform that adjusts to the skills of students.
76+ They use Haskell for all of their backend services and most of their tooling.
77+* Galois is a company that specializes in the research and development of
78+ trustworthy software systems for fields where failure is unacceptable. One of
79+ their most interesting projects is Copilot, a stream-based DSL for writing and
80+ monitoring embedded C programs.
81+* Serokell uses Haskell to great success for most of their day-to-day software
82+ development projects. They have used it to build the settlement layer of the
83+ Cardano blockchain, programming languages for the Tezos blockchain,
84+ cryptocurrency exchanges, a multi-currency wallet with its own DSL and more.
85+
86+## What are the benefits of using Haskell?
87+
88+Companies above list three things as the most significant benefits of Haskell:
89+
90+1. Expressive type system.
91+2. Strong correctness guarantees.
92+3. Easy refactoring.
93+
94+In addition, while Haskell is a great programming language for everyday
95+purposes, we can separate two popular use cases:
96+
97+1. Complex systems where strong guarantees are required (such as blockchains
98+ like Cardano and fintech projects like Klarna).
99+2. The second is compilers and DSLs. On our list, the examples for this use case
100+ are projects like Bond, Semantic, Copilot.
101+
102+Both of these use cases heavily benefit from the strengths of Haskell and manage
103+to dodge most of its cons. They can rightfully be called the “killer apps” of
104+Haskell.
105+
106+If you are considering a project in these two areas, it’s hard to go wrong with
107+picking Haskell.
108+
109+# Basic language constructs
110+
111+This file is actually a markdown file with a postprocessor run on it to extract
112+haskell code blocks like these:
113+
114+```haskell
115+a = 5
116+```
117+
118+Normal code is written in normal source code files with extension `.hs` called
119+**modules**. To write a comment, a double dash is used:
120+
121+```haskell
122+-- This is a comment inside code block in a literate Haskell file.
123+{- And this is a multiline comment.
124+ A little useless, isn't it? -}
125+```
126+
127+## Primitive Datatypes and Operators
128+
129+Of course, Haskell has numbers, booleans, characters, strings and whatnot:
130+
131+```haskell
132+b = a + 1 -- 6
133+c = 3 - 2 -- 1
134+d = 10 * 2 -- 20
135+e = 35 / 5
136+```
137+
138+However, if you load this file into a Haskell interpreter called `ghci`, you'll
139+see the following:
140+
141+```
142+~/haskell-lectures-2024 $ ghci 1.Intro.lhs
143+Loaded package environment from /home/turtle/.ghc/x86_64-linux-9.4.8/environments/default
144+GHCi, version 9.4.8: https://www.haskell.org/ghc/ :? for help
145+package flags have changed, resetting and loading new packages...
146+Loaded GHCi configuration from /home/turtle/haskell-2024/haskell-lectures-2024/.ghci
147+[1 of 2] Compiling Main ( 1.Intro.lhs, interpreted )
148+Ok, one module loaded.
149+ghci> e
150+7.0
151+```
152+
153+So division is not integer division by default. Actual integer division:
154+
155+```haskell
156+this_is_eight = 35 `div` 4
157+```
158+
159+Boolean operations:
160+
161+```haskell
162+f = not True
163+g = not False
164+h = True && False
165+i = True || False
166+j = 1 == 1
167+k = 1 /= 1
168+l = 1 < 10
169+```
170+
171+In the above examples, `not` is a function that takes one value. Haskell doesn't
172+need parentheses for function calls --- all the arguments are just listed after
173+the function. So the general pattern is: `func arg1 arg2 arg3...` See the
174+section on functions for information on how to write your own.
175+
176+Strings and characters:
177+
178+```haskell
179+m = "This is a string."
180+n = 'a'
181+```
182+
183+```haskell ignore
184+o = 'You cant use single quotes for strings.' -- error!
185+```
186+
187+Strings can be concatenated:
188+
189+```haskell
190+p = "Hello " ++ "world!"
191+```
192+
193+A string is a list of characters:
194+
195+```haskell
196+q = ['H', 'e', 'l', 'l', 'o']
197+```
198+
199+Lists can be indexed with the `!!` operator followed by an index
200+
201+```haskell
202+s = "This is a string" !! 0
203+```
204+
205+## Lists
206+
207+Every element in a list must have the same type. These two lists are equal:
208+
209+```haskell
210+l1 = [1, 2, 3, 4, 5]
211+l2 = [1..5]
212+```
213+
214+Ranges are versatile.
215+
216+```haskell
217+charRange = ['A'..'F'] -- "ABCDEF"
218+orderingRange = [LT .. GT] -- [LT, EQ, GT]
219+```
220+
221+You can create a step in a range.
222+
223+```haskell
224+evenStep = [0,2..10] -- [0, 2, 4, 6, 8, 10]
225+notStepped = [5..1] -- [] (Haskell defaults to incrementing)
226+decrementStep = [5,4..1] -- [5, 4, 3, 2, 1]
227+```
228+
229+Indexing into a list
230+
231+```haskell
232+thirdGlyph = [1..10] !! 3 -- 4 (zero-based indexing)
233+```
234+
235+You can also have infinite lists in Haskell!
236+
237+```haskell
238+nats = [1..] -- a list of all the natural numbers
239+```
240+
241+Infinite lists work because Haskell has "lazy evaluation". This means that
242+Haskell only evaluates things when it needs to. So you can ask for the 1000th
243+element of your list and Haskell will give it to you:
244+
245+```haskell
246+someNat = [1..] !! 999 -- 1000
247+```
248+
249+And now Haskell has evaluated elements 1 - 1000 of this list... but the rest of
250+the elements of this "infinite" list don't exist yet! Haskell won't actually
251+evaluate them until it needs to.
252+
253+Joining two lists:
254+
255+```haskell
256+joinedLists = [1..5] ++ [6..10]
257+```
258+
259+Adding to the head of a list:
260+
261+```haskell
262+headCat = 0:[1..5] -- [0, 1, 2, 3, 4, 5]
263+```
264+
265+More list operations
266+
267+```haskell
268+someHead = head [1..5] -- 1
269+someTail = tail [1..5] -- [2, 3, 4, 5]
270+someInit = init [1..5] -- [1, 2, 3, 4]
271+someLast = last [1..5] -- 5
272+```
273+
274+Actually, you can lookup them on [hoogle](https://hoogle.haskell.org/) or, even
275+better, find them there by their type signature!
276+
277+List comprehensions
278+
279+```haskell
280+comp = [x*2 | x <- [1..5]] -- [2, 4, 6, 8, 10]
281+```
282+
283+With a conditional
284+
285+```haskell
286+compCond = [x*2 | x <- [1..5], x*2 > 4] -- [6, 8, 10]
287+```
288+
289+With several iteratees
290+
291+```haskell
292+twoD = take 10 [x ^ 2 * y | x <- [1..], even x, x `mod` 3 == 0, y <- [1, -1]]
293+```
294+
295+## Tuples
296+
297+Every element in a tuple can be a different type, but a tuple has a fixed
298+length. A tuple:
299+
300+```haskell
301+tupleExample = ("haskell", 1)
302+```
303+
304+Accessing elements of a pair (i.e. a tuple of length 2)
305+
306+```haskell
307+someFst = fst ("haskell", 1) -- "haskell"
308+someSnd = snd ("haskell", 1) -- 1
309+```
310+
311+Pair element accessing does not work on n-tuples (i.e. triple, quadruple, etc)
312+
313+```haskell ignore
314+snd ("snd", "can't touch this", "da na na na") -- error! see function below
315+```
316+
317+## Functions
318+
319+A simple function that takes two variables
320+
321+```haskell
322+add a b = a + b
323+```
324+
325+Using the function
326+
327+```haskell
328+three = add 1 2 -- 3
329+```
330+
331+You can also put the function name between the two arguments with backticks:
332+
333+```haskell
334+alsoThree = 1 `add` 2 -- 3
335+```
336+
337+You can also define functions that have no letters! This lets you define your
338+own operators! Here's an operator that does integer division
339+
340+```haskell
341+(//) a b = a `div` b
342+eight = 35 // 4 -- 8
343+```
344+
345+### Guards
346+
347+An easy way to do branching in functions
348+
349+```haskell
350+fib x
351+ | x < 2 = 1
352+ | otherwise = fib (x - 1) + fib (x - 2)
353+```
354+
355+### Pattern matching
356+
357+Pattern matching is similar. Here we have given three different equations that
358+define `fib'`. Haskell will automatically use the first equation whose left hand
359+side pattern matches the value.
360+
361+```haskell
362+fib' 1 = 1
363+fib' 2 = 2
364+fib' x = fib' (x - 1) + fib' (x - 2)
365+```
366+
367+### Pattern matching on tuples
368+
369+```haskell
370+sndOfTriple (_, y, _) = y -- use a wild card (_) to bypass naming unused value
371+```
372+
373+### Pattern matching on lists
374+
375+Here `x` is the first element in the list, and `xs` is the rest of the list. We
376+can write our own map function:
377+
378+```haskell
379+myMap func [] = []
380+myMap func (x:xs) = func x:(myMap func xs)
381+```
382+
383+Anonymous functions are created with a backslash followed by all the arguments.
384+
385+```haskell
386+mapped = myMap (\x -> x + 2) [1..5] -- [3, 4, 5, 6, 7]
387+```
388+
389+### Using fold (called `inject` in some languages) with an anonymous function
390+
391+`foldl1` means fold left, and use the first value in the list as the initial
392+value for the accumulator.
393+
394+```haskell
395+usingFold = foldl1 (\acc x -> acc + x) [1..5] -- 15
396+```
397+
398+### Partial application
399+
400+If you don't pass in all the arguments to a function, it gets "partially
401+applied". That means it returns a function that takes the rest of the arguments.
402+
403+```haskell
404+foo = add 10 -- foo is now a function that takes a number and adds 10 to it
405+fifteen = foo 5 -- 15
406+```
407+
408+Another way to write the same thing. It is called a "section":
409+
410+```haskell
411+foo' = (10 +)
412+alsoFifteen = foo' 5 -- 15
413+```
414+
415+### Function composition
416+
417+The operator `.` chains functions together. For example, here `foo` is a
418+function that takes a value. It adds 10 to it, multiplies the result of that by
419+4, and then returns the final value.
420+
421+```haskell
422+foo'' = (4 *) . (10 +)
423+sixty = foo'' 5 -- 4*(10+5) = 60
424+```
425+
426+### Fixing precedence
427+
428+Haskell has an operator called `$`. This operator applies a function to a given
429+parameter. In contrast to standard function application, which has highest
430+possible priority of 10 and is left-associative, the `$` operator has priority
431+of 0 and is right-associative. Such a low priority means that the expression on
432+its right is applied as a parameter to the function on its left.
433+
434+Before:
435+
436+```haskell
437+evenSeven = even (fib 7) -- false
438+```
439+
440+Equivalently:
441+
442+```haskell
443+evenSeven' = even $ fib 7 -- false
444+```
445+
446+Composing functions:
447+
448+```haskell
449+evenSeven'' = even . fib $ 7 -- false
450+```
451+
452+## Type signatures
453+
454+Haskell has a very strong type system, and every valid expression has a type.
455+Some basic types:
456+
457+```haskell
458+five = 5 :: Integer
459+hello = "hello" :: String
460+truth = True :: Bool
461+```
462+
463+Functions have types too. `not` takes a boolean and returns a boolean:
464+
465+```haskell
466+not' = not :: Bool -> Bool
467+```
468+
469+Here's a function that takes two arguments:
470+
471+```haskell
472+add' = add :: Integer -> Integer -> Integer
473+```
474+
475+When you define a value, it's good practice to write its type above it:
476+
477+```haskell
478+double :: Integer -> Integer
479+double x = x * 2
480+```
481+
482+### Typed holes
483+
484+Haskell's type system allows one to use "typed holes" -- you can replace an
485+expression with an underscore and a compiler would tell you what is the expected
486+type of a missing expression:
487+
488+```haskell ignore
489+double' x = _ * 2 :: Integer
490+```
491+
492+## Control Flow and If Expressions
493+
494+if-expressions
495+
496+```haskell
497+haskell = if 1 == 1 then "awesome" else "awful" -- haskell = "awesome"
498+```
499+
500+if-expressions can be on multiple lines too, indentation is important
501+
502+```haskell
503+haskell' = if 1 == 1
504+ then "awesome"
505+ else "awful"
506+```
507+
508+Case expressions: Here's how you could parse command line arguments
509+
510+```haskell
511+parseArgs args =
512+ case args of
513+ "help" -> printHelp
514+ "start" -> startProgram
515+ _ -> putStrLn "bad args"
516+
517+printHelp = undefined -- see Hoogle to learn what this is
518+startProgram = undefined
519+```
520+
521+Haskell doesn't have loops; it uses recursion instead. map applies a function
522+over every element in a list
523+
524+```haskell
525+someEvens = map (*2) [1..5] -- [2, 4, 6, 8, 10]
526+```
527+
528+You can make a for function using map
529+
530+```haskell
531+for array func = map func array
532+```
533+
534+And then use it
535+
536+```haskell
537+strings = for [0..5] $ \i -> show i
538+```
539+
540+We could've written that like this too:
541+
542+```haskell
543+strs = for [0..5] show
544+```
545+
546+You can use `foldl` or `foldr` to reduce a list:
547+`foldl <fn> <initial value> <list>`
548+
549+```haskell
550+fortyThree = foldl (\x y -> 2*x + y) 4 [1,2,3] -- 43
551+```
552+
553+(This is the same as (2 * (2 * (2 * 4 + 1) + 2) + 3))
554+
555+While `foldl` is left-handed, `foldr` is right-handed
556+
557+```haskell
558+sixteen = foldr (\x y -> 2*x + y) 4 [1,2,3] -- 16
559+```
560+
561+(This is now the same as (2 * 1 + (2 * 2 + (2 * 3 + 4))))
562+
563+## Data Types
564+
565+A data type is declared with a 'type constructor' on the left and one or more
566+'data constructors' on the right, separated by the pipe | symbol. This is a
567+sum/union type. Each data constructor is a (possibly nullary) function that
568+creates an object of the type named by the type constructor.
569+
570+This is essentially an enum
571+
572+```haskell
573+data Color = Red | Blue | Green -- would be an enum in other languages
574+```
575+
576+Now you can use it in a function:
577+
578+```haskell
579+say :: Color -> String
580+say Red = "You are Red!"
581+say Blue = "You are Blue!"
582+say Green = "You are Green!"
583+```
584+
585+Note that the type constructor is used in the type signature and the data
586+constructors are used in the body of the function. Data constructors are
587+primarily pattern-matched against.
588+
589+This next one is a traditional container type holding two fields. In a type
590+declaration, data constructors take types as parameters. Data constructors can
591+have the same name as type constructors: this is common where the type only has
592+a single data constructor, although here we do not do this to reduce confusion
593+for newcomers.
594+
595+```haskell
596+data Point = Cartesian Float Float
597+```
598+
599+This can be used in a function like:
600+
601+```haskell
602+distance :: Point -> Point -> Float
603+distance (Cartesian x y) (Cartesian x' y') = sqrt $ dx + dy
604+ where dx = (x - x') ** 2
605+ dy = (y - y') ** 2
606+```
607+
608+Types can have multiple data constructors with arguments, too
609+
610+```haskell
611+data Name = Mononym String
612+ | FirstLastName String String
613+ | FullName String String String
614+```
615+
616+To make things clearer, we can use record syntax
617+
618+```haskell
619+data PointRecord = CartesianPoint2D { x :: Float, y :: Float }
620+ | PolarPoint2D { r :: Float, theta :: Float }
621+
622+myPoint = CartesianPoint2D { x = 7.0, y = 10.0 }
623+```
624+
625+Using record syntax automatically creates accessor functions:
626+
627+```haskell
628+xOfMyPoint = x myPoint -- 7.0
629+```
630+
631+Record syntax also allows a simple form of update
632+
633+```haskell
634+myPoint' = myPoint { x = 9.0 } -- CartesianPoint2D { x = 9.0, y = 10.0 }
635+```
636+
637+Even if a type is defined with record syntax, it can be declared like a simple
638+data constructor. This is fine:
639+
640+```haskell
641+myPoint'' = CartesianPoint2D 3.3 4.0
642+```
643+
644+It's also useful to pattern match data constructors in `case` expressions
645+
646+```haskell
647+distanceFromOrigin x =
648+ case x of (CartesianPoint2D x y) -> sqrt $ x ** 2 + y ** 2
649+ (PolarPoint2D r _) -> r
650+```
651+
652+Your data types can have type parameters too:
653+
654+```haskell ignore
655+data Maybe a = Nothing | Just a
656+```
657+
658+These are all `Maybe`s, but with different `a`s:
659+
660+```haskell
661+justHello = Just "hello" -- of type `Maybe String`
662+justOne = Just 1 -- of type `Maybe Int`
663+nothing = Nothing -- of type `Maybe a` for any `a`
664+```
665+
666+For convenience we can also create type synonyms with the `type` keyword
667+
668+```haskell
669+type String' = [Char]
670+```
671+
672+Unlike `data` types, type synonyms need no constructor, and can be used anywhere
673+a synonymous data type could be used. Say we have the following type synonyms
674+and items with the following type signatures:
675+
676+```haskell
677+-- For demonstration purposes, these types have no constructors
678+data Person
679+data Circle
680+
681+-- Types in which we are interested
682+type Weight = Float
683+type Height = Float
684+type Point2D = (Float, Float)
685+
686+getMyHeightAndWeight :: Person -> (Height, Weight)
687+getMyHeightAndWeight = undefined
688+
689+findCenter :: Circle -> Point2D
690+findCenter = undefined
691+
692+somePerson :: Person
693+somePerson = undefined
694+
695+someCircle :: Circle
696+someCircle = undefined
697+
698+distance2D :: Point2D -> Point2D -> Float
699+distance2D = undefined
700+```
701+
702+Then the following would compile and run without issue even though it does not
703+make sense semantically:
704+
705+```haskell
706+nonsense = distance2D (getMyHeightAndWeight somePerson) (findCenter someCircle)
707+```
708+
709+## Typeclasses
710+
711+Typeclasses are one way Haskell does polymorphism. They are similar to
712+interfaces in other languages: a typeclass defines a set of functions that must
713+work on any type that is in that typeclass.
714+
715+The
716+[Eq](https://hackage.haskell.org/package/base-4.19.0.0/docs/Prelude.html#t:Eq)
717+typeclass is for types whose instances can be tested for equality with one
718+another.
719+
720+```haskell ignore
721+class Eq a where
722+ (==) :: a -> a -> Bool
723+ (/=) :: a -> a -> Bool
724+ x == y = not (x /= y)
725+ x /= y = not (x == y)
726+```
727+
728+This defines a typeclass that requires two functions, `(==)` and `(/=)`. It also
729+declares that one function can be declared in terms of another, so it is enough
730+that __either__ the `(==)` function or the `(/=)` is defined and the other will
731+be "filled in" based on the typeclass definition.
732+
733+To make a type a member of a type class, the `instance` keyword is used
734+
735+```haskell
736+data TrafficLight = TLRed | TLYellow | TLGreen
737+
738+instance Eq TrafficLight where
739+ TLRed == TLRed = True
740+ TLGreen == TLGreen = True
741+ TLYellow == TLYellow = True
742+ _ == _ = False
743+```
744+
745+(Note that, while declaring `TrafficLight` constructors, we had to name
746+constructors differently in order for them to not clash with `Color`
747+constructors we defined earlier. It is common to either prefix constructor
748+names with type name abbreviation or define types in different modules
749+altogether)
750+
751+Now we can use `(==)` and `(/=)` with `TrafficLight` objects:
752+
753+```haskell
754+canProceedThrough :: TrafficLight -> Bool
755+canProceedThrough t = t /= TLRed
756+```
757+
758+You can NOT create an instance definition for a type synonym, though.
759+
760+Functions can be written to take typeclasses with type parameters, rather than
761+types, assuming that the function only relies on features of the typeclass:
762+
763+```haskell
764+isEqual :: Eq a => a -> a -> Bool
765+isEqual x y = x == y
766+```
767+
768+Note that `x` and `y` MUST be the same type, as they are both defined as being
769+of type parameter `a`. A typeclass does not state that different types in the
770+typeclass can be mixed together. So `isEqual Red 2` is invalid even though `2`
771+is an `Int` which is an instance of `Eq`, and `Red` is a `TrafficLight` which is
772+also an instance of `Eq`.
773+
774+Other common typeclasses are:
775+
776+* `Ord` for types that can be ordered, allowing you to use `>`, `<=`, etc.
777+* `Read` for types that can be created from a string representation
778+* `Show` for types that can be converted to a string for display
779+* `Num`, `Real`, `Integral`, `Fractional` for types that can do math
780+* `Enum` for types that can be stepped through
781+* `Bounded` for types with a maximum and minimum
782+
783+### Literals
784+
785+We used character, string and list literals back from the very start. It is
786+simple to understand what they mean and how to use them. However, numeric
787+literals are not so simple. If we ask GHCi: "what is the type of 2?", we get:
788+
789+```
790+ghci> :t 2
791+2 :: Num a => a
792+```
793+
794+So numeric literals are actually polymorphic and do not have a concrete type.
795+Not that this is not the same as casts because the following is not allowed:
796+
797+```haskell
798+two = 2 :: Integer
799+```
800+```haskell ignore
801+float = two * 0.5 -- would not pass the type check
802+```
803+
804+### Deriving
805+
806+Haskell can automatically make types part of `Eq`, `Ord`, `Read`, `Show`, `Enum`
807+and `Bounded` with the `deriving` keyword at the end of the type declaration
808+
809+```haskell
810+data PointDerives = Point Float Float deriving (Eq, Read, Show)
811+```
812+
813+In this case it is NOT necessary to create an `instance` definition.
814+
815+## Haskell IO
816+
817+While IO can't be explained fully without explaining monads, it is not hard to
818+explain enough to get going.
819+
820+When a Haskell program is executed, `main` is called. It must return a value of
821+type `IO a` for some type `a`. For example:
822+
823+```haskell
824+main :: IO ()
825+main = putStrLn $ "Hello, sky! " ++ (say Blue)
826+```
827+
828+(`putStrLn` has type `String -> IO ()`)
829+
830+It is easiest to do IO if you can implement your program as a function from
831+String to String. The function
832+
833+```haskell
834+interact' = interact :: (String -> String) -> IO ()
835+```
836+
837+Inputs some text, runs a function on it, and prints out the output.
838+
839+```haskell
840+countLines :: String -> String
841+countLines = show . length . lines
842+
843+main' = interact countLines
844+```
845+
846+You can think of a value of type `IO ()` as representing a sequence of actions
847+for the computer to do, much like a computer program written in an imperative
848+language. We can use the `do` notation to chain actions together. For example:
849+
850+```haskell
851+sayHello :: IO ()
852+sayHello = do
853+ putStrLn "What is your name?"
854+ name <- getLine -- this gets a line and gives it the name "name"
855+ putStrLn $ "Hello, " ++ name
856+```
857+
858+Exercise: write your own version of `interact` that only reads one line of
859+input.
860+
861+If you are running this module in GHCi, it can run any IO action on demand:
862+
863+```
864+ghci> sayHello
865+What is your name?
866+Pavel
867+Hello, Pavel
868+```
869+
870+Let's understand better how the function `getLine` we just used works. Its type
871+is:
872+
873+```haskell
874+getLine' = getLine :: IO String
875+```
876+
877+You can think of a value of type `IO a` as representing a computer program that
878+will generate a value of type `a` when executed (in addition to anything else it
879+does). We can name and reuse this value using `<-`. We can also make our own
880+action of type `IO String`:
881+
882+```haskell
883+action :: IO String
884+action = do
885+ putStrLn "This is a line. Duh"
886+ input1 <- getLine
887+ input2 <- getLine
888+ -- The type of the `do` statement is that of its last line.
889+ -- `return` is not a keyword, but merely a function
890+ return (input1 ++ "\n" ++ input2) -- return :: String -> IO String
891+```
892+
893+However, do-notation is not some compiler magic, this is just a syntactic sugar
894+over two operators called `>>` and `>>=`. The action below is the same as the
895+action above:
896+
897+```haskell
898+action' = putStrLn "This is a line. Duh" >> (getLine >>= (\input1 ->
899+ getLine >>= (\input2 -> return (input1 ++ "\n" ++ input2))))
900+```
901+
902+We can use this just like we used `getLine`:
903+
904+```haskell
905+main'' = do
906+ putStrLn "I will echo two lines!"
907+ result <- action
908+ putStrLn result
909+ putStrLn "This was all, folks!"
910+```
911+
912+The type `IO` is an example of a "monad". The way Haskell uses a monad to do IO
913+allows it to be a purely functional language. Any function that interacts with
914+the outside world (i.e. does IO) gets marked as `IO` in its type signature. This
915+lets us reason about which functions are "pure" (don't interact with the outside
916+world or modify state) and which functions aren't.
917+
918+This is a powerful feature, because it's easy to run pure functions
919+concurrently; so, concurrency in Haskell is very easy.
920+
921+## Monads
922+
923+Actually, `do`-notation has wider application than only constructing IO values.
924+Is is applicable for every _monad_:
925+
926+```
927+ghci> :i Monad
928+type Monad :: (* -> *) -> Constraint
929+class Applicative m => Monad m where
930+ (>>=) :: m a -> (a -> m b) -> m b
931+ (>>) :: m a -> m b -> m b
932+ return :: a -> m a
933+```
934+
935+In other words, `m` is a monad if it allows to construct "pure" values of type
936+`m a` from any value of type `a` and if it allows to sequence actions of type
937+`m a` and `m b` and yield a result of type `m b`, where the second action either
938+can (`(>>=)`) or cannot (`(>>)`) depend on the result of the first action.
939+
940+This is discussed more in detail in the next lecture.
941+
942+# Sources & References
943+
944+* [Wikipedia page on Haskell](https://en.wikipedia.org/wiki/Haskell)
945+* [Serokell blog post on Haskell in industry](https://serokell.io/blog/top-software-written-in-haskell)
946+* [Memo for basic Haskell constructions](https://learnxinyminutes.com/docs/haskell/)
947+* [Hoogle, Haskell code search](https://hoogle.haskell.org/)