• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
Haskell Tour (Part 2)
 

Haskell Tour (Part 2)

on

  • 2,382 views

We continue our introduction to Haskell. Today we talk about parametric types and list comprehensions.

We continue our introduction to Haskell. Today we talk about parametric types and list comprehensions.

Statistics

Views

Total Views
2,382
Views on SlideShare
1,220
Embed Views
1,162

Actions

Likes
4
Downloads
45
Comments
0

7 Embeds 1,162

http://codeaholics.hk 1137
http://feeds.feedburner.com 14
https://si0.twimg.com 4
http://posterous.com 3
https://abs.twimg.com 2
http://webcache.googleusercontent.com 1
https://twitter.com 1
More...

Accessibility

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Haskell Tour (Part 2) Haskell Tour (Part 2) Presentation Transcript

    • HaskellA Whirlwind Tour (Part II) William Taysom ~ 2011
    • Haskell is a non-strict,purely functionalprogramming languagewith strong,static type inference.
    • Review
    • Recursive Datadata Color = Red | Green | Blue | Mix Color Color
    • Recursive Functionshue :: Color -> Doublehue Red =0hue Green = 120hue Blue = 240
    • h = 60hue (Mix c c) = let h = hue c h = hue c m = average h h m = 180 m = norm (m + 180) m = 0 d = distance h m in case compare d 90 of LT -> m EQ -> nan h = 300 GT -> mnorm h | h < 360 = h | otherwise = norm (h - 360)
    • Parametric Types
    • Tuple (Product)data Point = Point Double Double
    • Tuple (Product)data Pair a b = Pair a b
    • Tuple (Product)data (a, b) = (a, b)-- Built-in syntax:-- definition only for illustrative purposes.
    • Tuple (Product)ghci> (Blue, False)data (a, b) = (a, b)-- Built-in syntax:-- definition only for illustrative purposes.
    • ghci> (Blue, False)(Blue,False)ghci>
    • ghci> (Blue, False)(Blue,False)ghci> (,) Blue False
    • ghci> (Blue, False)(Blue,False)ghci> (,) Blue False(Blue,False)ghci>
    • ghci> (Blue, False)(Blue,False)ghci> (,) Blue False(Blue,False)ghci> :t it
    • ghci> (Blue, False)(Blue,False)ghci> (,) Blue False(Blue,False)ghci> :t itit :: (Color, Bool)ghci>
    • ghci> (Blue, False)(Blue,False)ghci> (,) Blue False(Blue,False)ghci> :t itit :: (Color, Bool)ghci> :t (,)
    • ghci> (Blue, False)(Blue,False)ghci> (,) Blue False(Blue,False)ghci> :t itit :: (Color, Bool)ghci> :t (,)(,) :: a -> b -> (a, b)ghci>
    • ghci> (Blue, False)(Blue,False)ghci> (,) Blue False(Blue,False)ghci> :t itit :: (Color, Bool)ghci> :t (,)(,) :: a -> b -> (a, b)ghci> :kind (,)
    • ghci> (Blue, False)(Blue,False)ghci> (,) Blue False(Blue,False)ghci> :t itit :: (Color, Bool)ghci> :t (,)(,) :: a -> b -> (a, b)ghci> :kind (,)(,) :: * -> * -> *ghci>
    • ghci> (Blue, False)(Blue,False)ghci> (,) Blue False(Blue,False)ghci> :t itit :: (Color, Bool)ghci> :t (,)(,) :: a -> b -> (a, b)ghci> :kind (,)(,) :: * -> * -> *ghci> :k Color
    • ghci> (Blue, False)(Blue,False)ghci> (,) Blue False(Blue,False)ghci> :t itit :: (Color, Bool)ghci> :t (,)(,) :: a -> b -> (a, b)ghci> :kind (,)(,) :: * -> * -> *ghci> :k ColorColor :: *ghci>
    • Color :: *ghci>
    • Color :: *ghci> :t (Red, Blue, Green)
    • Color :: *ghci> :t (Red, Blue, Green)(Red, Blue, Green) :: (Color, Color, Color)ghci>
    • Color :: *ghci> :t (Red, Blue, Green)(Red, Blue, Green) :: (Color, Color, Color)ghci> :t (,,)
    • Color :: *ghci> :t (Red, Blue, Green)(Red, Blue, Green) :: (Color, Color, Color)ghci> :t (,,)(,,) :: a -> b -> c -> (a, b, c)ghci>
    • Color :: *ghci> :t (Red, Blue, Green)(Red, Blue, Green) :: (Color, Color, Color)ghci> :t (,,)(,,) :: a -> b -> c -> (a, b, c)ghci> :t (,,,)
    • Color :: *ghci> :t (Red, Blue, Green)(Red, Blue, Green) :: (Color, Color, Color)ghci> :t (,,)(,,) :: a -> b -> c -> (a, b, c)ghci> :t (,,,)(,,,) :: a -> b -> c -> d -> (a, b, c, d)ghci>
    • Color :: *ghci> :t (Red, Blue, Green)(Red, Blue, Green) :: (Color, Color, Color)ghci> :t (,,)(,,) :: a -> b -> c -> (a, b, c)ghci> :t (,,,)(,,,) :: a -> b -> c -> d -> (a, b, c, d)ghci> :t ()
    • Color :: *ghci> :t (Red, Blue, Green)(Red, Blue, Green) :: (Color, Color, Color)ghci> :t (,,)(,,) :: a -> b -> c -> (a, b, c)ghci> :t (,,,)(,,,) :: a -> b -> c -> d -> (a, b, c, d)ghci> :t ()() :: ()ghci>
    • Color :: *ghci> :t (Red, Blue, Green)(Red, Blue, Green) :: (Color, Color, Color)ghci> :t (,,)(,,) :: a -> b -> c -> (a, b, c)ghci> :t (,,,)(,,,) :: a -> b -> c -> d -> (a, b, c, d)ghci> :t ()() :: ()ghci> -- Trivial is similar to void.
    • Either (Sum)Color :: *ghci> :t (Red, Blue, Green)(Red, Blue, Green) :: (Color, Color, Color)ghci>Either a b = Left a | Right b data :t (,,)(,,) :: a -> b -> c -> (a, b, c)ghci> :t (,,,)(,,,) :: a -> b -> c -> d -> (a, b, c, d)ghci> :t ()() :: ()ghci> -- Trivial is similar to void.ghci>
    • Either (Sum)data Either a b = Left a | Right b
    • Maybe (Optional)data Maybe a = Nothing | Just a
    • hue :: Color -> Doublehue Red =0hue Green = 120hue Blue = 240hue (Mix c c) = ... sometimes NaN
    • hue :: Color -> Doublehue Red =0hue Green = 120hue Blue = 240hue (Mix c c) = ... sometimes nothing
    • hue :: Color -> Maybe Doublehue Red =0hue Green = 120hue Blue = 240hue (Mix c c) = ... sometimes nothing
    • hue :: Color -> Maybe Doublehue Red = Just 0hue Green = Just 120hue Blue = Just 240hue (Mix c c) = ... sometimes nothing
    • hue :: Color -> Maybe Doublehue Red = Just 0hue Green = Just 120hue Blue = Just 240hue (Mix c c) = let ... stuff ... in case compare d 90 of LT -> m EQ -> nan GT -> m
    • hue :: Color -> Maybe Doublehue Red = Just 0hue Green = Just 120hue Blue = Just 240hue (Mix c c) = let ... stuff ... in case compare d 90 of LT -> Just m EQ -> nan GT -> Just m
    • hue :: Color -> Maybe Doublehue Red = Just 0hue Green = Just 120hue Blue = Just 240hue (Mix c c) = let ... stuff ... in case compare d 90 of LT -> Just m EQ -> Nothing GT -> Just m
    • hue :: Color -> Maybe Doublehue Red = Just 0hue Green = Just 120hue Blue = Just 240hue (Mix c c) = let h = hue c h = hue c ... stuff ... in case compare d 90 of LT -> Just m EQ -> Nothing GT -> Just m
    • hue (Mix c c) = let h = hue c h = hue c ...
    • hue (Mix c c) = let h = hue c h = hue c ...
    • hue (Mix c c) = let (h, h) = (hue c, hue c) ...
    • hue (Mix c c) = case (hue c, hue c) of (h, h) -> let ...
    • hue (Mix c c) = case (hue c, hue c) of (Just h, Just h) -> let ...
    • hue (Mix c c) = case (hue c, hue c) of (Just h, Just h) -> let ... (Just h, Nothing) -> ... (Nothing, Just h) -> ... (Nothing, Nothing) -> ...
    • hue (Mix c c) = case (hue c, hue c) of (Just h, Just h) -> let ... (Just h, Nothing) -> Nothing (Nothing, Just h) -> Nothing (Nothing, Nothing) -> Nothing
    • hue (Mix c c) = case (hue c, hue c) of (Just h, Just h) -> let ... _ -> Nothing
    • hue (Mix c c) = case (hue c, hue c) of (Just h, Just h) -> let m = average h h m = norm (m + 180) d = distance h m in case compare d 90 of LT -> Just m EQ -> Nothing GT -> Just m _ -> Nothing
    • ParametricPolymorphismid x = xconst x _ = xflip f x y = f y x
    • ParametricPolymorphismid :: a -> aid x = xconst x _ = xflip f x y = f y x
    • ParametricPolymorphismid :: a -> aid x = xconst :: a -> b -> aconst x _ = xflip f x y = f y x
    • ParametricPolymorphismid :: a -> aid x = xconst :: a -> b -> aconst x _ = xflip :: (a -> b -> c) -> b -> a -> cflip f x y = f y x
    • ParametricPolymorphisminfixr . -- defaults to 9(f . g) x = f (g x)
    • ParametricPolymorphism(.) :: (b -> c) -> (a -> b) -> a -> cinfixr . -- defaults to 9(f . g) x = f (g x)
    • ParametricPolymorphism(.) :: (b -> c) -> (a -> b) -> a -> cinfixr . -- defaults to 9(f . g) x = f (g x)isN :: Double -> BoolisN = not . isNaN
    • ParametricPolymorphism(.) :: (b -> c) -> (a -> b) -> a -> cinfixr . -- defaults to 9(f . g) x = f (g x)isN :: Double -> BoolisN = not . isNaNcelsiusToFahrenheit :: Double -> DoublecelsiusToFahrenheit t = 9/5 * t + 32
    • ParametricPolymorphism(.) :: (b -> c) -> (a -> b) -> a -> cinfixr . -- defaults to 9(f . g) x = f (g x)isN :: Double -> BoolisN = not . isNaNcelsiusToFahrenheit :: Double -> DoublecelsiusToFahrenheit t = 9/5 * t + 32celsiusToFahrenheit = (32 +) . (9/5 *)
    • ParametricPolymorphisminfixr 0 $ -- very low precedence.f$x=fx
    • ParametricPolymorphism($) :: (a -> b) -> a -> binfixr 0 $ -- very low precedence.f$x=fx
    • ParametricPolymorphism($) :: (a -> b) -> a -> binfixr 0 $ -- very low precedence.f$x=fx-- Allows you to drop parenthesis:n = sqrt ( abs ( cos 1))n = sqrt $ abs $ cos 1
    • List (Stream)data List a = Nil | Cons a (List a)
    • List (Stream)data [a] = [] | a:[a]-- Built-in syntax:-- definition only for illustrative purposes.
    • List (Stream)ghci> [1,2,3]data [a] = [] | a:[a]-- Built-in syntax:-- definition only for illustrative purposes.
    • ghci> [1,2,3][1,2,3]ghci>
    • ghci> [1,2,3][1,2,3]ghci> 1:[2,3]
    • ghci> [1,2,3][1,2,3]ghci> 1:[2,3][1,2,3]ghci>
    • ghci> [1,2,3][1,2,3]ghci> 1:[2,3][1,2,3]ghci> 1:2:3:[]
    • ghci> [1,2,3][1,2,3]ghci> 1:[2,3][1,2,3]ghci> 1:2:3:[][1,2,3]ghci>
    • ghci> [1,2,3][1,2,3]ghci> 1:[2,3][1,2,3]ghci> 1:2:3:[][1,2,3]ghci> :t (:)
    • ghci> [1,2,3][1,2,3]ghci> 1:[2,3][1,2,3]ghci> 1:2:3:[][1,2,3]ghci> :t (:)(:) :: a -> [a] -> [a]ghci>
    • ghci> [1,2,3][1,2,3]ghci> 1:[2,3][1,2,3]ghci> 1:2:3:[][1,2,3]ghci> :t (:)(:) :: a -> [a] -> [a]ghci> :t []
    • Charactersghci> [1,2,3][1,2,3]ghci> 1:[2,3][1,2,3] c = cghci> 1:2:3:[] six = 6[1,2,3] tab = tghci> :t (:)(:) :: aisAlpha, isDigit :: Char -> Bool isSpace, -> [a] -> [a]ghci> Char -> Int ord :: :t [][] :: Int -> Char chr :: [a]ghci>
    • Charactersc = csix = 6tab = tisSpace, isAlpha, isDigit :: Char -> Boolord :: Char -> Intchr :: Int -> Char
    • Strings (Type Synonym)type String = [Char]
    • Strings (Type Synonym)ghci> :info Stringtype String = [Char]
    • ghci> :info Stringtype String = [Char] ! Defined in --GHC.Baseghci>
    • ghci> :info Stringtype String = [Char] ! Defined in --GHC.Baseghci> [h, e, l, l, o]
    • ghci> :info Stringtype String = [Char] ! Defined in --GHC.Baseghci> [h, e, l, l, o]"hello"ghci>
    • ghci> :info Stringtype String = [Char] ! Defined in --GHC.Baseghci> [h, e, l, l, o]"hello"ghci> :t error
    • ghci> :info Stringtype String = [Char] ! Defined in --GHC.Baseghci> [h, e, l, l, o]"hello"ghci> :t errorerror :: [Char] -> aghci>
    • ghci> :info Stringtype String = [Char] ! Defined in --GHC.Baseghci> [h, e, l, l, o]"hello"ghci> :t errorerror :: [Char] -> aghci> error "oops"
    • Arithmetic Sequencesghci> :info Stringtype String = [Char] ! Defined in --GHC.Baseghci> [h, e, l, l, o] one_ten = [1..10]"hello" a_z = [a..z]ghci> :t errorerror :: [Char] -> aghci> error "oops"*** Exception: oopsghci>
    • Arithmetic Sequencesone_ten = [1..10]a_z = [a..z]
    • Arithmetic Sequencesnats = [1..]
    • Lengthlength :: [a] -> Intlength [] =0length (_:xs)= 1 + length xslength one_ten --> 10length a_z --> 26
    • Mapmap :: (a -> b) -> [a] -> [b]map f [] = []map f (x:xs) = f x : map f xsmap ord "abc" --> [97, 98, 99]
    • Append(++) :: [a] -> [a] -> [a]infixr 5 ++[] ++ ys = ys(x:xs) ++ ys = x : (xs ++ ys)"hello" ++ " " ++ "world" --> "hello world"
    • Filterfilter :: (a -> Bool) -> [a] -> [a]filter p [] = []filter p (x:xs) |px = x : filter p xs | otherwise = filter p xsfilter (> 7) one_ten --> [8, 9, 10]
    • Foldfoldr :: (a -> b -> b) -> b -> [a] -> bfoldr f z [] =zfoldr f z (x:xs) = f x (foldr f x xs)foldr (*) 1 [1..5] --> 120
    • Concat (Flattening)concat :: [[a]] -> [a]concat = foldr (++) []concat ["hello", ", ", "world"] --> "hello, world"
    • ListComprehensions
    • List Comprehensionsdivides x y = rem y x == 0divisors x = [d | d <- [1..x], d `divides` x]
    • Generators[ (a, a, a) | a <- nats][(1,1,1),(2,2,2),(3,3,3),⋯]
    • Generators[ (a, b, c) | a <- nats, b <- nats, c <- nats][(1,1,1),(1,1,2),(1,1,3),⋯]
    • Generators[ (a, b, c) | a <- nats, b <- nats, c <- nats][(1,1,1),(1,1,2),(1,1,3),⋯](1,2,3) (1,3,2)(2,1,3) (3,1,2)(2,3,1) (3,2,1)
    • Generators[ (a, b, c) | a <- nats, b <- [1..a], c <- [1..b]][(1,1,1),(2,1,1),(2,2,1),⋯]
    • Generators[ (a, b, c) | c <- nats, b <- [1..c], a <- [1..b]][(1,1,1),(1,1,2),(1,2,2),⋯]
    • Guards[ (a, b, c) | c <- nats, b <- [1..c], a <- [1..b], a^2 + b^2 == c^2][(3,4,5),(6,8,10),(5,12,13),⋯]
    • Local Declaration[ (a, b, c) | c <- nats, b <- [1..c], a <- [1..b], a^2 + b^2 == c^2, ... commonDivisors == [1]][(3,4,5),(5,12,13),(8,15,17),⋯]
    • Local Declaration[ (a, b, c) | c <- nats, b <- [1..c], a <- [1..b], a^2 + b^2 == c^2, let commonDivisors = [d | d <- divisors a, d `divides` b, d `divides` c], commonDivisors == [1]][(3,4,5),(5,12,13),(8,15,17),⋯]
    • Local Declaration[ (a, b, c) | c <- nats, b <- [1..c], a <- [1..b], a^2 + b^2 == c^2, let d = gcd a b, d == 1][(3,4,5),(5,12,13),(8,15,17),⋯]
    • Recursionprimes = sieve [2..] where sieve (p:xs) = p : sieve [x | x <- xs, rem x p /= 0]
    • Recursionprimes = sieve [2..] where sieve (p:xs) = p : sieve [x | x <- xs, rem x p /= 0]primes
    • Recursionprimes = sieve [2..] where sieve (p:xs) = p : sieve [x | x <- xs, rem x p /= 0]sieve [2..]
    • Recursionprimes = sieve [2..] where sieve (p:xs) = p : sieve [x | x <- xs, rem x p /= 0]sieve (2:[3..])
    • Recursionprimes = sieve [2..] where sieve (p:xs) = p : sieve [x | x <- xs, rem x p /= 0]2 : sieve [x | x <- [3..], rem x 2 /= 0]
    • Recursionprimes = sieve [2..] where sieve (p:xs) = p : sieve [x | x <- xs, rem x p /= 0]2 : sieve [x | x <- 3:[4..], rem x 2 /= 0]
    • Recursionprimes = sieve [2..] where sieve (p:xs) = p : sieve [x | x <- xs, rem x p /= 0]2 : sieve (3:[x | x <- [4..], rem x 2 /= 0])
    • Recursionprimes = sieve [2..] where sieve (p:xs) = p : sieve [x | x <- xs, rem x p /= 0]2 : 3 : sieve [x | x <- [x | x <- [4..], rem x 2 /= 0], rem x 3 /= 0]
    • Recursionprimes = sieve [2..] where sieve (p:xs) = p : sieve [x | x <- xs, rem x p /= 0]2 : 3 : sieve [x | x <- [x | x <- 4:[5..], rem x 2 /= 0], rem x 3 /= 0]
    • Recursionprimes = sieve [2..] where sieve (p:xs) = p : sieve [x | x <- xs, rem x p /= 0]2 : 3 : sieve [x | x <- [x | x <- [5..], rem x 2 /= 0], rem x 3 /= 0]
    • Recursionprimes = sieve [2..] where sieve (p:xs) = p : sieve [x | x <- xs, rem x p /= 0]2 : 3 : sieve [x | x <- [x | x <- 5:[6..], rem x 2 /= 0], rem x 3 /= 0]
    • Recursionprimes = sieve [2..] where sieve (p:xs) = p : sieve [x | x <- xs, rem x p /= 0]2 : 3 : sieve [x | x <- 5:[x | x <- [6..], rem x 2 /= 0], rem x 3 /= 0]
    • Recursionprimes = sieve [2..] where sieve (p:xs) = p : sieve [x | x <- xs, rem x p /= 0]2 : 3 : sieve (5:[x | x <- [x | x <- [6..], rem x 2 /= 0], rem x 3 /= 0])
    • Recursionprimes = sieve [2..] where sieve (p:xs) = p : sieve [x | x <- xs, rem x p /= 0]2 : 3 : 5 : sieve [x | x <- [x | x <- [x | x <- [6..], rem x 2 /= 0], rem x 3 /= 0]), rem x 5 /= 0]
    • Recursionprimes = sieve [2..] where sieve (p:xs) = p : sieve [x | x <- xs, rem x p /= 0]2 : 3 : 5 : sieve [x | x <- [x | x <- [x | x <- 6:[7..], rem x 2 /= 0], rem x 3 /= 0]), rem x 5 /= 0]
    • Recursionprimes = sieve [2..] where sieve (p:xs) = p : sieve [x | x <- xs, rem x p /= 0]2 : 3 : 5 : sieve [x | x <- [x | x <- [x | x <- [7..], rem x 2 /= 0], rem x 3 /= 0]), rem x 5 /= 0]
    • Recursionprimes = sieve [2..] where sieve (p:xs) = p : sieve [x | x <- xs, rem x p /= 0]2 : 3 : 5 : sieve [x | x <- [x | x <- [x | x <- 7:[8..], rem x 2 /= 0], rem x 3 /= 0]), rem x 5 /= 0]
    • Recursionprimes = sieve [2..] where sieve (p:xs) = p : sieve [x | x <- xs, rem x p /= 0]2 : 3 : 5 : sieve [x | x <- [x | x <- 7:[x | x <- [8..], rem x 2 /= 0], rem x 3 /= 0]), rem x 5 /= 0]
    • Recursionprimes = sieve [2..] where sieve (p:xs) = p : sieve [x | x <- xs, rem x p /= 0]2 : 3 : 5 : sieve [x | x <- 7:[x | x <- [x | x <- [8..], rem x 2 /= 0], rem x 3 /= 0]), rem x 5 /= 0]
    • Recursionprimes = sieve [2..] where sieve (p:xs) = p : sieve [x | x <- xs, rem x p /= 0]2 : 3 : 5 : sieve (7:[x | x <- [x | x <- [x | x <- [8..], rem x 2 /= 0], rem x 3 /= 0]), rem x 5 /= 0])
    • Recursionprimes = sieve [2..] where sieve (p:xs) = p : sieve [x | x <- xs, rem x p /= 0]2 : 3 : 5 : 7 : sieve ⋯
    • Recursionprimes = sieve [2..] where sieve (p:xs) = p : sieve [x | x <- xs, rem x p /= 0][2, 3, 5, 7, sieve ⋯]
    • To be continued...
    • SummaryHaskell has parametric types.List Comprehensions are cool.
    • Preview: Infinite Listsprimes = sieve [2..] where sieve (p:xs) = p : sieve [x | x <- xs, rem x p /= 0]
    • Preview: IO (echo.hs)import System.Environment (getArgs)import Data.List (intercalate)main = do args <- getArgs putStrLn (intercalate " " args)
    • Preview: Parsers
    • Preview: Parse JSONdata Value = String String | Number Double | Object [(String, Value)] | Array [Value] | Bool Bool | Null
    • Preview: Parse JSONvalue = String <$>jsstring <|> Number <$>number <|> Object <$>commaGroup { pair } <|> Array <$>commaGroup [ value ] <|> Bool True <$ string "true" <|> Bool False <$ string "false" <|> Null <$ string "null"
    • Preview: Parse JSONpair :: Parser (String, Value)pair = do s <- jsstring sp_char_sp : v <- value spaces return (s, v)
    • To be continued...