Haskell in Harsh Words
Table of Contents
The Fuck is Haskell?
A pure, lazy, functional programming language. Basically, it is something that happens when like-minded cool people come together.
Meaning of the above bullshit words?
Functional
- All hail functions. Children of the idea behind lambda calculus. Use functions just like any other sort of values.
- Evaluate not execute.
Pure
- Immutability is the key.
- Fuck all side-effects.
- Deterministic as fuck.
- Benefits: equational reasoning, parallelism, happiness
Lazy
- Infinity? ez.
- Compositional programming — you feel like Mozart.
- Disadvantage: Wot is time? Wot is space?
Haskell, the new cool guy in campus
Types
- Statically typed: run time errors compile-time errors
- Expressive: the code is the documentation
- Expressive: brings clarity into coding
Abstraction
- Eat, Code, Sleep,
Repeat: Haskell has polymorphism, higher-order functions and type classes — so fuck repetition.
- Think about the big picture and don't cry about some stupid exception.
What can I do with it?
- Program Correctness (QuickCheck)
- Fail safe programming (Cardano)
- High-load concurrent programming (web back-end)
Haskell: A Functional Programming Langauge
What does it mean for Haskell to be a functional programming language? Well, it means that Haskell follows the principle of functional programming — a programming paradigm where functions are the basic building blocks of computation.
Def: A function is a mapping that takes one or more arguments and produces a single result.
Properties of Haskell
- Consice programs
- Powerful type system
- List comprehension
- Recursive functions
- Higher-order functions
- Effectful functions
- Generic functions
- Lazy evaluation
- Equational reasoning
First Steps
Haskell comes with a large number of built-in functions, which are defined in a library file called the standard prelude.
head <list>
tail <list>
take <num> <list>
drop <num> <list>
sum <list>
reverse <list>
product <list>
Function Format
Just as in lambda calculus haskell follows a fixed pattern for functions. Here are some examples to elaborate:
- as
f x
- as
f x y
- as
f (g x)
- as
f x (g y)
- as
f x * g y
Examples
-- Program 1
main = print (a ++ b ++ c)
a = [((2**3) * 4)]
b = [(2*3) + (4*5)]
c = [2 + (3 * (4**5))]
-- Program 2
main = print (n)
n = (a `div` (length xs))
where
a = 10
xs = [1 .. 5]
-- Program 3
main = print (a [1 .. 5])
a xs = sum (drop (length xs - 1) (take (length xs) xs))main = putStrLn "hello, world"
Types and class
Types
- They are a collection of related values.
f :: A -> B
ande :: A
then,f e :: B
- Bool – logical values
- Char – single characters
- String – strings of characters
- Int – fixed-precision integers
- Integer – arbitrary-precision integers
- Float – single-precision floating-point numbers
- Double – double-precision floating-point numbers
[[’a’,’b’],[’c’,’d’,’e’]] :: [[Char]]
- List types —
["One","Two","Three"] :: [String]
- Tuple types —
("Yes",True,’a’) :: (String,Bool,Char)
- Function types —
not :: Bool -> Bool
andadd :: (Int,Int) -> Int
- Interestingly, we can model functions in a different way as well. For e.g.,
add x y = x + y
results in add being of type(Int, Int) -> Int
as well as can be modelled asInt -> (Int -> Int)
- Polymorphic types — for example
length :: [a] -> Int
andzip :: [a] -> [b] -> [(a, b)]
Classes
- They are collections of types that support certain overloaded operations called methods.
- Eq —
(==) :: a -> a -> Bool
- Ord —
<, >, min, max
- Show —
show :: a -> String
- Read —
read :: String -> a
- Num — e.g.,
(+), (-), negate, abs, signum
with(+) :: a -> a -> a
- Integral —
div :: a -> a -> a
andmod :: a -> a -> a
, also Int and Integer types are instances of this class.
- Fractional — Float and Double are instances of this class. We also have methods such as
/
andrecip
.
Functions
-- Let's see an example
even :: a -> Bool
even n = (n `mod` 2 == 0)
-- Conditional using "if else"
signum n = if n > 0 then 1
else if n < 0 then -1
else 0
-- Conditional using "such that"
signum n | n > 0 = 1
| n < 0 = -1
| otherwise = 0
Let us now introduce some really cool implementation techniques in haskell with respect to defining functions.
- Pattern Matching
-- Define functions using '_' len [] = 0 len (_:xs) = 1 + len xs initials :: String -> String -> String initials firstname lastname = [f] ++ ". " ++ [l] ++ "." where (f:_) = firstname (l:_) = lastname -- Defining using '_' fundamentally test :: Int -> Int test 0 = 1 test 1 = 2 test _ = 0
- Lambda Functions
\x -> x + 1
- Taking input
-- Just mentioned here so that one can try out problems with input import Control.Arrow ((>>>)) main :: IO () main = interact $ lines >>> head >>> read >>> solve >>> (++ "\n") solve :: Int -> String -- Type 2 import Control.Arrow ((>>>)) main :: IO () main = interact $ words >>> map read >>> solve >>> show >>> (++ "\n") solve :: [Integer] -> Integer