@@ -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