Haskell 101
Haskell is...
- Functional (functions are data)
- Strong- and Statically-typed
- Lazy
- Pure
Environment
GHCI
Interactive console! (REPL - Read Evaluate Print Loop)
Useful commands:
:set +t
- print type after evaluation:set +s
- print time/memory stats after evaluation
To declare something in GHCI, you have to prefix it with let
let x = 2
Compilation
ghc Main.hs
Almost a script
runghc Main.hs
Type system
Basics
Values
2 :: Int
[1,2,3] :: [Int]
"abc" :: [Char]
4:5:6:[] :: [Int]
['a', 'b', 'c'] :: [Char]
(1, 'a', True) :: (Int, Char, Bool)
Functions
-- one argument
sumInts :: [Int] -> Int
-- two arguments
add :: Int -> Int -> Int
Advanced
Generic functions
length :: [a] -> Int
reverse :: [a] -> [a]
Generic addition in C++
template <typename T> T add(T x, T y) {
return x + y;
}
Generic addition in Haskell
add :: Num a => a -> a -> a
add x y = x + y
Constraints (context)
find :: Eq a => a -> [a] -> a
sort :: Ord a => [a] -> [a]
Function calls
Regular
sum [1, 2, 3]
add 4 (-5)
(+) 6 1
head "abc"
tail "abc"
Operators
2 - 4
3.4 / 2
6 `add` 1
Lambdas
square = \x -> x * x
Prelude> let square = \x -> x * x
Prelude> :t square
square :: Num a => a -> a
Currying, partial application
add x y = x + y
add' x = \y -> x + y
add'' = \x -> \y -> x + y
-- add, add', add'' :: Int -> Int -> Int
add5 = add 5
realAdd = (+)
Laziness
Infinite lists
[1..]
[1,3..]
Evaluated only as far as needed
Prelude> take 3 [1..]
[1,3,5]
Functions everywhere
Collection of functions
Prelude> :t [add'', (+)]
[add'', (+)] :: Num a => [a -> a -> a]
Higher-order functions
Prelude> filter odd [1,2,3,4,5]
[1,3,5]
Prelude> :t filter
filter :: (a -> Bool) -> [a] -> [a]
Prelude> zipWith (+) [1,3..] [4..10]
[5,8,11,14,17,20,23]
Prelude> :t zipWith
zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
Function chaining
Prelude> take 3 (filter odd [1..])
[1,3,5]
Prelude> take 3 $ filter odd [1..]
[1,3,5]
Prelude> (take 3 . filter odd) [1..]
[1,3,5]
Pattern matching
head' (x:xs) = x
head'' (x:_) = x
take 0 _ = []
take _ [] = []
take n (x:xs) = x:take (n-1) xs
Guards
take _ [] = []
take n (x:xs)
| n <= 0 = []
| otherwise = x:take (n-1) xs
List comprehension
pairs = [ (x,y) | x <- [1..3], y <- [x+1,x+3..7] ]
oddNaturals = [ x | x <- [1..], odd x ]
Mandatory Fibonacci sequence
fib = 0:1:[ x+y | (x,y) <- zip fib (tail fib) ]