Haskell – (and Monads) –



Haskell – (and Monads) –

0 0


haskell_talk

Quick introductory talk to dev/como on Haskell and Monads

On Github igraves / haskell_talk

Haskell

(and Monads)

Programming in Haskell

The Language

Lazy

fst (x,y) = y
fst (5+5,1+1) == 2

5+5? Never evaluated.

Pure

foo :: Int -> Int
foo i = putStrLn i --Nope

Effects outside the type are not allowed.

Strict

True == 1 -- Won't type check

Types are strict. Implicit coercion isn't allowed. Relations between non-matching types must be specified.

Inferred

y :: Int
y = 1 
f x = x
f y -- Typechecker determines f :: Int -> Int

The typechecker fills in the gaps on types for you.

Functions

f x = x --Identity
not False = True --Explicit matching
not True  = False
f g x = g x -- Higher order

Lambdas

--Identity
y x = x
y = \z -> z 
--Both of the above are equivalent to each other

Application

--Apply incr to 1 and bind that to y
y = incr 1
-- y == 2

Giving a function its argument is called "applying it to its argument".

Types

One Argument

incr :: Int -> Int
incr x = x + 1

Two Arguments

add :: Int -> Int -> Int
add a b = a + b

Three Arguments

add3 :: Int -> Int -> Int -> Int
add3 a b c = a + b + c

Partial Application

incr :: Int -> Int
incr = add 1

If a function isn't given all its all of its arguments, a new function that takes the remaining arguments is given instead of a result.

Lists

Similar to other languages

 x :: [Int]
 x =  [1,2,3,4]
 --equivalent definition.  Empty list at the end of cons's
 x =  1 : 2 : 3 : 4 : []
 
 y = [5]

-- z == [1,2,3,4,5] Append
 z = x ++ y 

Strings are actually lists of Char

type String = [Char]

-- "abc" == 'a' : 'b' : 'c' : []

Above is a type synonym declaration.

Polymorphism

Some popular polymorphic type signatures

id :: a -> a

filter :: (a -> Bool) -> [a] -> [a]

map :: (a -> b) -> [a] -> [b]

--Mapping over lists, most generally
map :: (a -> b) -> [a] -> [b]

Variables with the same name are one type. Variables with different names are not assumed to be the same type.

Data Types

Algebraic Data Types

data Color = Red | Green | Blue
--import Data.Word
--Word8 is an unsigned byte
--newtype only allows one type constructor
data HexColor = RGB Word8 Word8 Word8 | White | Black -- ....

RGB :: Word8 -> Word8 -> Word8 -> HexColor
White :: HexColor
Red :: Color
  • HexColor is a Type Constructor
  • RGB is a Data Constructor that constructs a HexColor

Tuples

-- A pair tuple
(5,6.0) :: (Int, Double)
-- a 3-tuple
("hi",7,'a') :: (String, Int, Char)

Tuples can be about as long as you want.

Advanced Type Constructors

-- A simple something or nothing
data Maybe a = Nothing | Just a
-- Can be singly recursive like a list
data List a  = Cons a (List a) | Nil
-- Can be doubly recursive like a tree
data Tree a  = Node (Tree a) a (Tree a) | Leaf --Binary Tree
-- Can have more than one type in our containers
data Either a b = Left a | Right b

Pattern Matching

Can explictly match with functions

-- Matching a Boolean as before, explicitly
not :: Bool -> Bool
not True  = False --True is a data constructor we match against
not False = True

--List cons matching
head :: [a] -> a
head []     = error "Oh no!"
head (a:as) = a

str_hex :: HexColor -> String
str_hex White = "White"
str_hex Black = "Black"
--Lets bind the RGB values to variables
--Show turns things to String, more on that later
str_hex (RGB c1 c2 c3) = "RGB " ++ (show c1) ++ " " 
                                ++ (show c2) ++ " "
                                ++ (show c3)

Pattern Match Failures

--Given some function that gets a value from Maybe a
--Encountering nothing will fail
fromJust :: Maybe a -> a
fromJust (Just x) = x
--Or the list head case, empty list fails
head :: [a] -> a
head (x:xs) = x

If a function can't match your patterns, the program will crash. Handling situations like this is up to the developer.

Type Classes

Overloading / ad-hoc Polymorphism

class Show a where
  show :: a -> String
  --Actual Show has two other methods
  --But you only need show to be minimally complete

class Ord a where
  compare :: a -> a -> Ordering
  (<) :: a -> a -> Bool
  (>=) :: a -> a -> Bool
  --A number of others

class Eq a where
  (==) :: a -> a -> Bool

Classes in Haskell are like Interfaces in Java, Protocols in Objective-C, or abc's in Python(?).

Instances of classes

instance Show Color where
    show Red   = "Red"
    show Green = "Green"
    show Blue  = "Blue"
-- Or you can derive Show to get the equivalent functionality to the above
 data Color = Red | Green | Blue deriving (Show)
-- This only works if you have nullary constructors OR, all types for each
-- constructor are themselves already in Show (basic types usually are)

Monads

Problems with "pure" Haskell

  • Sequenced operations are handy and we want them
  • Sharing results between separate computations is awkward
  • Side Effects Remain an issue we need to track somehow

Enter the Monad

class Monad m where
   return :: a -> m a
   (>>=)  :: m a -> (a -> m b) -> m b
   (>>)   :: m a -> m b -> m b
   -- (>>) is (>>=) such that a >>= (\_ -> b)
   -- We'll ignore it from here on

Monads are "contexts in which we can run computations" that have particular useful traits that allow us to model side-effects in a meaningful way.

Monads are wrapper types like the ones that we saw earlier (Maybe a).

Return

return :: a -> m a
Return takes a value and wraps it in the context of the monad. Enables you to place values into a monad so you can use them inside the monad.

Bind

(>>=) :: m a -> (a -> m b)
Runs the monad on the left to get its result of type a Gives that result to the function on the right Constructs continuting monadic function to run
m a >>= (a -> m b) >>= (b -> m c) :: m c

The Monad Laws

Anything that is an instance of Monad must obey the following laws

Left Identity

return a >>= f ~= f a

Right Identity

m >>= return ~= m

Associativity

(m >>= f) >>= g  ~= m >>= (\x -> f x >>= g)

Monads in the Typeclassopedia

So Let's try something

Conclusion

Cool if you don't normally use it

  • Forces you to rethink patterns you forgot were patterns
  • Makes you more aware of the computational power you require
  • Gets you back in the types realm ;-)

Popular Haskell Applications/Stacks

  • Web: Yesod, Snap, Happstack, aeson, Heist, Scotty, websockets
  • PL Parsers: Parsec
  • Symbolic Reasoning: SBV
  • Parallel/Concurrency: Parallel Package, STM
  • Data Processing: Conduit, Pipes
  • Bonus Points: Lenses, Comonads

Resources

Thanks!