Preface
- Configure hexchat or irrsi in emacs to access #haskell-beginners freenode channel
- Spaced repetition and iterative deepening are effective strategies of learning.
- Solving exercises and returning to concepts can help develop intuition.
- Reason through the code samples and exercises in your head first, then type them out - either in REPL or in Source file.
- If you are stuck in a exercise for an extended period of time than come back later.
- All modern functional languages are based on lambda calculus.
- Solving the same problem in different ways increases your fluency and comfort with the way haskell works
- Writing yo6ur own thought processes can clarify your thoughts and make the solving of similar problems easier.
Chapter 1 - All you need is lambda
- In the Lambda expression - λx.x and λx.xa
- .x is called bound variable, a is called free variable.
- λx is called head and xa is called body.
- Beta-reduction - eliminating the head λx as its main purpose was to bind to a variable.
- Divergence - when x is substituted in λx.x then we get the same expression, thus it is in non-reducible form.
Chapter 2 - Hello Haskell
-
Reducible expressions are called redexes. Ex: 1+1
-
Currying - applying a series of nested functions, each to an argument.
-
Haskell evaluates to weak head normal form by default. ex: (f -> (1, 2+f)) 2
(1 , 2 + 2) 2+2 is not evaluated until the last possible moment.
-
Module names are capitalised. camelCase is used for variable names
-
2 + 2 is a reducible expression. 4 is a value(irreducible constant).
-
modulo 12 is used for a 12 hour clock. 12 is equivalent to both itself and 0.
-
$ allows everything on the right of expression to be evaluated first.
-
Ex: (+1) 2. (+1) is called sectioning and allows us to pass
Chapter 3 - Strings
-
concat :: a -> [a]
-
Prelude has functions with exceptions:
head "" "" !! 4
Chapter 4 - Basic Datatypes
-
Int size has a min and max range. Integer size depends on the system.
-
floating point can shift how many bits it uses to represent numbers before or after the decimal point.(DO NOT USE IN BUSINESS APPLICATIONS.)
-
In the case of Integer, and most numeric datatypes, these data constructors are not written out because they include an infinite series of whole numbers. We would need infinite data constructors stretching up from zero.
-
Num typeclass is a superclass of fractional typeclass.
-
values of Fractional a => a default to the floating point doucble. It is better to use arbitrary precision sibling to Integer.
4 / 2
-
x /= 5. (/=) symbol means not equal to.
-
Ord typeclass has lexicographic ordering. ex: Chris < Julie
-
Scope is a way to refer to where a named binding to an expression is valid.
-
data (,) a b
-
[char] - String, [a] - List
Chapter 5 - Types
-
(->) is an infix operator and right associative. ex:
f :: a -> a -> a -- associates to f :: a -> (a -> a)
-
function applicative is left associative. So, the leftmost or outermost arguments are evaluated first.
-
Int can make use of the Num and Integral typeclasses because it has instances of both.
-
Haskell's type inference is built on Damas-Hindley-Milner type system.
-
f 1 2 f :: Num a => a -> a -> a :t f 1 f 1 :: Num a => a -> a
Chapter 6 - Types
- Do not use Read for Bool.
- Enum must be members of Ord, All members of Ord must be member of Num
- Don't use Int as an Implicit sum type as C programmers commonly do. . . .
Chapter 11 - Algebraic Datatypes
-
Type constructors are used only in Type Signatures, Data constructors are used at term level.
-
Type and data constructors that take no arguments are constants. In the context of type constructor, its type signature is a concrete type. ex: data PugType = pugData
-
:kind - to check the kind of a type.
-
Bool and [Int] are fully applied, concrete types, so their kind signatures have no function arrows.
-
an empty list has to be applied to a concrete type before it is itself a concrete type.
:k [] * -> *
chapter 12 - Signaling adversity
-
type name = String type Age = Integer data Person = Person Name Age deriving Show mkPerson :: Name -> Age -> Maybe Person mkPerson name age | name /= "" && age >= 0 = Just $ Person name age | otherwise = nothin
- :: syntax usually means "has type of".
- kind * is the kind of all standard lifeted types, while types that have the kind # are unlifted.