Haskell
Functional Programming
is scary
Unfamiliar
Functor
Mappable
Catamorphism
Collapsible
Foldable
Monad
Flatmappable
Chainable
AndThenable
Computation builder
( I'll come back to this one )
Monoid
Aggregatable
Currying
Currying?
Applicatives
Applicatives?
Object Oriented
Programming
is scary
very much so.
Inheritance
Covariance
Polymorphism
SOLID
SRP,OCP,LSP
DIP
Functional Programming
Ideas
Maths
is your
Friend
Mathematical assertions are
Precise
Mathematical assertions are usually
Generalized
( You can often apply them to many different instances )
Mathematical reasoning is/can be
Proved
Functions are pure
Given the same inputs, always will return same output
( Referential transparency )
Types
are not
Classes
What are types?
Int is a type
String is a type
User is a type
Functions
are types
Int -> Int
(+3)
Functions
are
Things
You can:
Return functions from functions
Pass functions as parameters
Writing functions in different ways
add :: Int -> Int -> Int
add x y = x + y
add :: Int -> Int -> Int
add = (\x y -> x + y)
add :: Int -> (Int -> Int)
add x = (\y -> x + y)
three = 1 + 2
three = (+) 2 1
add1 = (+) 2
Missing a parameter?
Composition
Everywhere!
show :: Int -> String
length :: String -> Int
digitCount :: Int -> Int
digitCount :: Int -> Int
digitCount value = length (show value)
digitCount :: Int -> Int
digitCount value = length . show value
digitCount :: Int -> Int
digitCount = length . show
. is a function!
show is (a -> b) (Int -> String)
length is (b -> c) (String -> Int)
the number you pass in is a
(.) :: (b -> c) -> (a -> b) -> a -> c
Functions
all the
Way Down
Types
are your
Friends
Use types to represent
Constraints
data Suit = Club | Diamond | Spades | Diamond
data Rank = Two
| Three
| Four
| Five
| Six
| Seven
| Eight
| Nine
| Ten
| Jack
| Queen
| King
| Ace
data Card = Card Suit Rank
type Deck = [Card]
Use types to indicate
Errors
parseInt :: String -> Int
parseInt :: String -> Maybe Int
-
No nulls
-
No exceptions
Make illegal states
Unrepresentable
data Status = Verified | Unverified
Use types for
State Machines
data ShoppingCart = Empty | Active [Item] | Paid [Item]
Beautiful clean
internal model
Dirty unclean outside world
The Great Gate
Monoids, Functors, Applicatives and Monads
Are all different algebras
They are ideas about computation
Not just specific to Haskell
Functions of type
a -> b
Transform values of type a to values of type b
(+1) :: Int -> Int
show :: Int -> String
( Increments a number by 1 )
( Returns the string representation of a number )
But what if a value is in some kind of container?
eg a maybe
Maybe
data Maybe a = Nothing | Just a
2 -- a value
Just 2 -- a value with context.
When a value is wrapped in a context (eg a list, or maybe)
You can't apply a normal function to it.
fmap
fmap knows how to apply a function to a value in a context
fmap (+3) (Just 2)
Just 5
But how does fmap do this wizardry?
Functor is a typeclass
A typeclass is a sort of interface that defines some behavior.
If a type is part of a typeclass,
that means it implements the behaviour the typeclass describes
class Functor f where
fmap :: (a -> b) -> f a -> f b
To make data type f a functor
You'll need to implement this function for your data type
The map function
map :: (a -> b) -> [a] -> [b]
map :: (Int -> String) -> [Int] -> [String]
map show [1, 2, 3, 4]
["1", "2", "3", "4"]
map (+1) [1, 2, 3, 4]
[2, 3, 4, 5]
If something is a functor
then there exists a function called fmap that will lift transformations from
a -> b
to
f a -> f b
Examples
fmap specialized to lists has the type:
(a -> b) -> ([a] -> [b])
fmap specialized to Maybe has the type:
(a -> b) -> (Maybe a -> Maybe b)
We can also have containers with functions in them
Subtitle
Values
2
2 (+1) = 3
Context
Just 1
data Maybe a = Nothing | Just a
Haskell
By ..
Haskell
- 1,900