@@ -1,784 +0,0 @@
5−As written in Wikipedia:
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
15−** Where is Haskell used?
17−Haskell is used in academia and in industry:
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
31− * TidalCycles is a domain special language for live coding musical patterns,
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
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.
61−*** Some more examples from Serokell
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
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
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.
89−** What are the benefits of using Haskell?
91−Companies above list three things as the most significant benefits of Haskell:
93− 1. Expressive type system.
94− 2. Strong correctness guarantees.
97−In addition, while Haskell is a great programming language for everyday
98−purposes, we can separate two popular use cases:
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.
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
109−If you are considering a project in these two areas, it’s hard to go wrong with
112−* Basic language constructs
114−This file is actually a /literate Haskell/ file with extension @.lhs@ where
115−every piece of code is indented with @>@ like this:
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:
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? -}
126−** Primitive Datatypes and Operators
128−Of course, Haskell has numbers, booleans, characters, strings and whatnot:
135−However, if you load this file into a Haskell interpreter called @ghci@, you'll
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.
147−So division is not integer division by default. Actual integer division:
149−> this_is_eight = 35 `div` 4
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.
166−Strings and characters:
168−> m = "This is a string."
170−> -- o = 'You cant use single quotes for strings.' -- error!
172−Strings can be concatenated:
174−> p = "Hello " ++ "world!"
176−A string is a list of characters:
178−> q = ['H', 'e', 'l', 'l', 'o']
180−Lists can be indexed with the @!!@ operator followed by an index
182−> s = "This is a string" !! 0
186−Every element in a list must have the same type. These two lists are equal:
188−> l1 = [1, 2, 3, 4, 5]
191−Ranges are versatile.
193−> charRange = ['A'..'F'] -- "ABCDEF"
194−> orderingRange = [LT .. GT] -- [LT, EQ, GT]
196−You can create a step in a range.
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]
204−> thirdGlyph = [1..10] !! 3 -- 4 (zero-based indexing)
206−You can also have infinite lists in Haskell!
208−> nats = [1..] -- a list of all the natural numbers
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:
214−> someNat = [1..] !! 999 -- 1000
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.
222−> joinedLists = [1..5] ++ [6..10]
224−Adding to the head of a list:
226−> headCat = 0:[1..5] -- [0, 1, 2, 3, 4, 5]
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
235−Actually, you can lookup them on [hoogle](https://hoogle.haskell.org/) or, even
236−better, find them there by their type signature!
240−> comp = [x*2 | x <- [1..5]] -- [2, 4, 6, 8, 10]
244−> compCond = [x*2 | x <- [1..5], x*2 > 4] -- [6, 8, 10]
246−With several iteratees
248−> twoD = take 10 [x ^ 2 * y | x <- [1..], even x, x `mod` 3 == 0, y <- [1, -1]]
252−Every element in a tuple can be a different type, but a tuple has a fixed
255−> tupleExample = ("haskell", 1)
257−Accessing elements of a pair (i.e. a tuple of length 2)
259−> someFst = fst ("haskell", 1) -- "haskell"
260−> someSnd = snd ("haskell", 1) -- 1
262−Pair element accessing does not work on n-tuples (i.e. triple, quadruple, etc)
264−> -- snd ("snd", "can't touch this", "da na na na") -- error! see function below
268−A simple function that takes two variables
274−> three = add 1 2 -- 3
276−You can also put the function name between the two arguments with backticks:
278−> alsoThree = 1 `add` 2 -- 3
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
283−> (//) a b = a `div` b
284−> eight = 35 // 4 -- 8
288−An easy way to do branching in functions
292−> | otherwise = fib (x - 1) + fib (x - 2)
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.
302−> fib' x = fib' (x - 1) + fib' (x - 2)
304−*** Pattern matching on tuples
306−> sndOfTriple (_, y, _) = y -- use a wild card (_) to bypass naming unused value
308−*** Pattern matching on lists
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:
314−> myMap func (x:xs) = func x:(myMap func xs)
316−Anonymous functions are created with a backslash followed by all the arguments.
318−> mapped = myMap (\x -> x + 2) [1..5] -- [3, 4, 5, 6, 7]
320−*** Using fold (called @inject@ in some languages) with an anonymous function
322−foldl1 means fold left, and use the first value in the list as the initial value
325−> usingFold = foldl1 (\acc x -> acc + x) [1..5] -- 15
327−*** Partial application
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.
332−> foo = add 10 -- foo is now a function that takes a number and adds 10 to it
333−> fifteen = foo 5 -- 15
335−Another way to write the same thing. It is called a "section":
338−> alsoFifteen = foo' 5 -- 15
340−*** Function composition
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.
346−> foo'' = (4 *) . (10 +)
347−> sixty = foo'' 5 -- 4*(10+5) = 60
349−*** Fixing precedence
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.
359−> evenSeven = even (fib 7) -- false
363−> evenSeven' = even $ fib 7 -- false
367−> evenSeven'' = even . fib $ 7 -- false
371−Haskell has a very strong type system, and every valid expression has a type.
374−> five = 5 :: Integer
375−> hello = "hello" :: String
376−> truth = True :: Bool
378−Functions have types too. @not@ takes a boolean and returns a boolean:
380−> not' = not :: Bool -> Bool
382−Here's a function that takes two arguments:
384−> add' = add :: Integer -> Integer -> Integer
386−When you define a value, it's good practice to write its type above it:
388−> double :: Integer -> Integer
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:
397−> -- double' x = _ * 2 :: Integer
399−** Control Flow and If Expressions
403−> haskell = if 1 == 1 then "awesome" else "awful" -- haskell = "awesome"
405−if-expressions can be on multiple lines too, indentation is important
407−> haskell' = if 1 == 1
411−Case expressions: Here's how you could parse command line arguments
415−> "help" -> printHelp
416−> "start" -> startProgram
417−> _ -> putStrLn "bad args"
419−> printHelp = undefined -- see Hoogle to learn what this is
420−> startProgram = undefined
422−Haskell doesn't have loops; it uses recursion instead. map applies a function
423−over every element in a list
425−> someEvens = map (*2) [1..5] -- [2, 4, 6, 8, 10]
427−You can make a for function using map
429−> for array func = map func array
433−> strings = for [0..5] $ \i -> show i
435−We could've written that like this too:
437−> strs = for [0..5] show
439−You can use foldl or foldr to reduce a list: @foldl <fn> <initial value> <list>@
441−> fortyThree = foldl (\x y -> 2*x + y) 4 [1,2,3] -- 43
443−This is the same as (2 * (2 * (2 * 4 + 1) + 2) + 3)
445−While foldl is left-handed, foldr is right-handed
447−> sixteen = foldr (\x y -> 2*x + y) 4 [1,2,3] -- 16
449−This is now the same as (2 * 1 + (2 * 2 + (2 * 3 + 4)))
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.
458−This is essentially an enum
460−> data Color = Red | Blue | Green -- enum in Rust
462−Now you can use it in a function:
464−> say :: Color -> String
465−> say Red = "You are Red!"
466−> say Blue = "You are Blue!"
467−> say Green = "You are Green!"
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.
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
479−> data Point = Cartesian Float Float
481−This can be used in a function like:
483−> distance :: Point -> Point -> Float
484−> distance (Cartesian x y) (Cartesian x' y') = sqrt $ dx + dy
485−> where dx = (x - x') ** 2
488−Types can have multiple data constructors with arguments, too
490−> data Name = Mononym String
491−> | FirstLastName String String
492−> | FullName String String String
494−To make things clearer, we can use record syntax
496−> data PointRecord = CartesianPoint2D { x :: Float, y :: Float }
497−> | PolarPoint2D { r :: Float, theta :: Float }
499−> myPoint = CartesianPoint2D { x = 7.0, y = 10.0 }
501−Using record syntax automatically creates accessor functions:
503−> xOfMyPoint = x myPoint -- 7.0
505−Record syntax also allows a simple form of update
507−> myPoint' = myPoint { x = 9.0 } -- CartesianPoint2D { x = 9.0, y = 10.0 }
509−Even if a type is defined with record syntax, it can be declared like a simple
510−data constructor. This is fine:
512−> myPoint'' = CartesianPoint2D 3.3 4.0
514−It's also useful to pattern match data constructors in `case` expressions
516−> distanceFromOrigin x =
517−> case x of (CartesianPoint2D x y) -> sqrt $ x ** 2 + y ** 2
518−> (PolarPoint2D r _) -> r
520−Your data types can have type parameters too:
523−data Maybe a = Nothing | Just a
526−These are all Maybes, but with different @a@s:
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`
532−For convenience we can also create type synonyms with the @type@ keyword
534−> type String' = [Char]
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
540−> -- For demonstration purposes, these types have no constructors
544−> -- Types in which we are interested
545−> type Weight = Float
546−> type Height = Float
547−> type Point2D = (Float, Float)
549−> getMyHeightAndWeight :: Person -> (Height, Weight)
550−> getMyHeightAndWeight = undefined
552−> findCenter :: Circle -> Point2D
553−> findCenter = undefined
555−> somePerson :: Person
556−> somePerson = undefined
558−> someCircle :: Circle
559−> someCircle = undefined
561−> distance2D :: Point2D -> Point2D -> Float
562−> distance2D = undefined
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:
567−> nonsense = distance2D (getMyHeightAndWeight somePerson) (findCenter someCircle)
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.
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
582− (==) :: a -> a -> Bool
583− (/=) :: a -> a -> Bool
584− x == y = not (x /= y)
585− x /= y = not (x == y)
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.
593−To make a type a member of a type class, the @instance@ keyword is used
595−> data TrafficLight = TLRed | TLYellow | TLGreen
597−> instance Eq TrafficLight where
598−> TLRed == TLRed = True
599−> TLGreen == TLGreen = True
600−> TLYellow == TLYellow = True
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
609−Now we can use @(==)@ and @(/=)@ with TrafficLight objects:
611−> canProceedThrough :: TrafficLight -> Bool
612−> canProceedThrough t = t /= TLRed
614−You can NOT create an instance definition for a type synonym, though.
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:
619−> isEqual :: Eq a => a -> a -> Bool
620−> isEqual x y = x == y
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
628−Other common typeclasses are:
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
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:
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:
652−> -- float = two * 0.5 -- would not pass the type check
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
659−> data PointDerives = Point Float Float deriving (Eq, Read, Show)
661−In this case it is NOT necessary to create an @instance@ definition.
665−While IO can't be explained fully without explaining monads, it is not hard to
666−explain enough to get going.
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:
672−> main = putStrLn $ "Hello, sky! " ++ (say Blue)
674−(@putStrLn@ has type @String -> IO ()@)
676−It is easiest to do IO if you can implement your program as a function from
677−String to String. The function
679−> interact' = interact :: (String -> String) -> IO ()
681−Inputs some text, runs a function on it, and prints out the output.
683−> countLines :: String -> String
684−> countLines = show . length . lines
686−> main' = interact countLines
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:
694−> putStrLn "What is your name?"
695−> name <- getLine -- this gets a line and gives it the name "name"
696−> putStrLn $ "Hello, " ++ name
698−Exercise: write your own version of @interact@ that only reads one line of
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>@.
706−Or, if you are running this module in GHCi, it can run any IO action on demand:
715−Let's understand better how the function @getLine@ we just used works. Its type
718−> getLine' = getLine :: IO String
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@:
725−> action :: IO String
727−> putStrLn "This is a line. Duh"
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
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
738−> action' = putStrLn "This is a line" >> (getLine >>= (\input1 ->
739−> getLine >>= (\input2 -> return (input1 ++ "\n" ++ input2))))
741−We can use this just like we used @getLine@:
744−> putStrLn "I will echo two lines!"
747−> putStrLn "This was all, folks!"
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.
755−This is a powerful feature, because it's easy to run pure functions
756−concurrently; so, concurrency in Haskell is very easy.
760−Actually, @do@-notation has wider application than only constructing IO values.
761−Is is applicable for every /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
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.
777−This is discussed more in detail in the next lecture.
779−* Sources & References
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 @@