Haskell Tour (Part 2)

2,612 views

Published on

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

Published in: Technology, Art & Photos
0 Comments
8 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
2,612
On SlideShare
0
From Embeds
0
Number of Embeds
1,162
Actions
Shares
0
Downloads
60
Comments
0
Likes
8
Embeds 0
No embeds

No notes for slide

Haskell Tour (Part 2)

  1. 1. HaskellA Whirlwind Tour (Part II) William Taysom ~ 2011
  2. 2. Haskell is a non-strict,purely functionalprogramming languagewith strong,static type inference.
  3. 3. Review
  4. 4. Recursive Datadata Color = Red | Green | Blue | Mix Color Color
  5. 5. Recursive Functionshue :: Color -> Doublehue Red =0hue Green = 120hue Blue = 240
  6. 6. 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)
  7. 7. Parametric Types
  8. 8. Tuple (Product)data Point = Point Double Double
  9. 9. Tuple (Product)data Pair a b = Pair a b
  10. 10. Tuple (Product)data (a, b) = (a, b)-- Built-in syntax:-- definition only for illustrative purposes.
  11. 11. Tuple (Product)ghci> (Blue, False)data (a, b) = (a, b)-- Built-in syntax:-- definition only for illustrative purposes.
  12. 12. ghci> (Blue, False)(Blue,False)ghci>
  13. 13. ghci> (Blue, False)(Blue,False)ghci> (,) Blue False
  14. 14. ghci> (Blue, False)(Blue,False)ghci> (,) Blue False(Blue,False)ghci>
  15. 15. ghci> (Blue, False)(Blue,False)ghci> (,) Blue False(Blue,False)ghci> :t it
  16. 16. ghci> (Blue, False)(Blue,False)ghci> (,) Blue False(Blue,False)ghci> :t itit :: (Color, Bool)ghci>
  17. 17. ghci> (Blue, False)(Blue,False)ghci> (,) Blue False(Blue,False)ghci> :t itit :: (Color, Bool)ghci> :t (,)
  18. 18. ghci> (Blue, False)(Blue,False)ghci> (,) Blue False(Blue,False)ghci> :t itit :: (Color, Bool)ghci> :t (,)(,) :: a -> b -> (a, b)ghci>
  19. 19. ghci> (Blue, False)(Blue,False)ghci> (,) Blue False(Blue,False)ghci> :t itit :: (Color, Bool)ghci> :t (,)(,) :: a -> b -> (a, b)ghci> :kind (,)
  20. 20. ghci> (Blue, False)(Blue,False)ghci> (,) Blue False(Blue,False)ghci> :t itit :: (Color, Bool)ghci> :t (,)(,) :: a -> b -> (a, b)ghci> :kind (,)(,) :: * -> * -> *ghci>
  21. 21. 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
  22. 22. 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>
  23. 23. Color :: *ghci>
  24. 24. Color :: *ghci> :t (Red, Blue, Green)
  25. 25. Color :: *ghci> :t (Red, Blue, Green)(Red, Blue, Green) :: (Color, Color, Color)ghci>
  26. 26. Color :: *ghci> :t (Red, Blue, Green)(Red, Blue, Green) :: (Color, Color, Color)ghci> :t (,,)
  27. 27. Color :: *ghci> :t (Red, Blue, Green)(Red, Blue, Green) :: (Color, Color, Color)ghci> :t (,,)(,,) :: a -> b -> c -> (a, b, c)ghci>
  28. 28. Color :: *ghci> :t (Red, Blue, Green)(Red, Blue, Green) :: (Color, Color, Color)ghci> :t (,,)(,,) :: a -> b -> c -> (a, b, c)ghci> :t (,,,)
  29. 29. 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>
  30. 30. 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 ()
  31. 31. 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>
  32. 32. 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.
  33. 33. 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>
  34. 34. Either (Sum)data Either a b = Left a | Right b
  35. 35. Maybe (Optional)data Maybe a = Nothing | Just a
  36. 36. hue :: Color -> Doublehue Red =0hue Green = 120hue Blue = 240hue (Mix c c) = ... sometimes NaN
  37. 37. hue :: Color -> Doublehue Red =0hue Green = 120hue Blue = 240hue (Mix c c) = ... sometimes nothing
  38. 38. hue :: Color -> Maybe Doublehue Red =0hue Green = 120hue Blue = 240hue (Mix c c) = ... sometimes nothing
  39. 39. hue :: Color -> Maybe Doublehue Red = Just 0hue Green = Just 120hue Blue = Just 240hue (Mix c c) = ... sometimes nothing
  40. 40. 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
  41. 41. 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
  42. 42. 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
  43. 43. 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
  44. 44. hue (Mix c c) = let h = hue c h = hue c ...
  45. 45. hue (Mix c c) = let h = hue c h = hue c ...
  46. 46. hue (Mix c c) = let (h, h) = (hue c, hue c) ...
  47. 47. hue (Mix c c) = case (hue c, hue c) of (h, h) -> let ...
  48. 48. hue (Mix c c) = case (hue c, hue c) of (Just h, Just h) -> let ...
  49. 49. hue (Mix c c) = case (hue c, hue c) of (Just h, Just h) -> let ... (Just h, Nothing) -> ... (Nothing, Just h) -> ... (Nothing, Nothing) -> ...
  50. 50. 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
  51. 51. hue (Mix c c) = case (hue c, hue c) of (Just h, Just h) -> let ... _ -> Nothing
  52. 52. 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
  53. 53. ParametricPolymorphismid x = xconst x _ = xflip f x y = f y x
  54. 54. ParametricPolymorphismid :: a -> aid x = xconst x _ = xflip f x y = f y x
  55. 55. ParametricPolymorphismid :: a -> aid x = xconst :: a -> b -> aconst x _ = xflip f x y = f y x
  56. 56. ParametricPolymorphismid :: a -> aid x = xconst :: a -> b -> aconst x _ = xflip :: (a -> b -> c) -> b -> a -> cflip f x y = f y x
  57. 57. ParametricPolymorphisminfixr . -- defaults to 9(f . g) x = f (g x)
  58. 58. ParametricPolymorphism(.) :: (b -> c) -> (a -> b) -> a -> cinfixr . -- defaults to 9(f . g) x = f (g x)
  59. 59. ParametricPolymorphism(.) :: (b -> c) -> (a -> b) -> a -> cinfixr . -- defaults to 9(f . g) x = f (g x)isN :: Double -> BoolisN = not . isNaN
  60. 60. 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
  61. 61. 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 *)
  62. 62. ParametricPolymorphisminfixr 0 $ -- very low precedence.f$x=fx
  63. 63. ParametricPolymorphism($) :: (a -> b) -> a -> binfixr 0 $ -- very low precedence.f$x=fx
  64. 64. 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
  65. 65. List (Stream)data List a = Nil | Cons a (List a)
  66. 66. List (Stream)data [a] = [] | a:[a]-- Built-in syntax:-- definition only for illustrative purposes.
  67. 67. List (Stream)ghci> [1,2,3]data [a] = [] | a:[a]-- Built-in syntax:-- definition only for illustrative purposes.
  68. 68. ghci> [1,2,3][1,2,3]ghci>
  69. 69. ghci> [1,2,3][1,2,3]ghci> 1:[2,3]
  70. 70. ghci> [1,2,3][1,2,3]ghci> 1:[2,3][1,2,3]ghci>
  71. 71. ghci> [1,2,3][1,2,3]ghci> 1:[2,3][1,2,3]ghci> 1:2:3:[]
  72. 72. ghci> [1,2,3][1,2,3]ghci> 1:[2,3][1,2,3]ghci> 1:2:3:[][1,2,3]ghci>
  73. 73. ghci> [1,2,3][1,2,3]ghci> 1:[2,3][1,2,3]ghci> 1:2:3:[][1,2,3]ghci> :t (:)
  74. 74. 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>
  75. 75. 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 []
  76. 76. 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>
  77. 77. Charactersc = csix = 6tab = tisSpace, isAlpha, isDigit :: Char -> Boolord :: Char -> Intchr :: Int -> Char
  78. 78. Strings (Type Synonym)type String = [Char]
  79. 79. Strings (Type Synonym)ghci> :info Stringtype String = [Char]
  80. 80. ghci> :info Stringtype String = [Char] ! Defined in --GHC.Baseghci>
  81. 81. ghci> :info Stringtype String = [Char] ! Defined in --GHC.Baseghci> [h, e, l, l, o]
  82. 82. ghci> :info Stringtype String = [Char] ! Defined in --GHC.Baseghci> [h, e, l, l, o]"hello"ghci>
  83. 83. ghci> :info Stringtype String = [Char] ! Defined in --GHC.Baseghci> [h, e, l, l, o]"hello"ghci> :t error
  84. 84. ghci> :info Stringtype String = [Char] ! Defined in --GHC.Baseghci> [h, e, l, l, o]"hello"ghci> :t errorerror :: [Char] -> aghci>
  85. 85. ghci> :info Stringtype String = [Char] ! Defined in --GHC.Baseghci> [h, e, l, l, o]"hello"ghci> :t errorerror :: [Char] -> aghci> error "oops"
  86. 86. 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>
  87. 87. Arithmetic Sequencesone_ten = [1..10]a_z = [a..z]
  88. 88. Arithmetic Sequencesnats = [1..]
  89. 89. Lengthlength :: [a] -> Intlength [] =0length (_:xs)= 1 + length xslength one_ten --> 10length a_z --> 26
  90. 90. Mapmap :: (a -> b) -> [a] -> [b]map f [] = []map f (x:xs) = f x : map f xsmap ord "abc" --> [97, 98, 99]
  91. 91. Append(++) :: [a] -> [a] -> [a]infixr 5 ++[] ++ ys = ys(x:xs) ++ ys = x : (xs ++ ys)"hello" ++ " " ++ "world" --> "hello world"
  92. 92. 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]
  93. 93. 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
  94. 94. Concat (Flattening)concat :: [[a]] -> [a]concat = foldr (++) []concat ["hello", ", ", "world"] --> "hello, world"
  95. 95. ListComprehensions
  96. 96. List Comprehensionsdivides x y = rem y x == 0divisors x = [d | d <- [1..x], d `divides` x]
  97. 97. Generators[ (a, a, a) | a <- nats][(1,1,1),(2,2,2),(3,3,3),⋯]
  98. 98. Generators[ (a, b, c) | a <- nats, b <- nats, c <- nats][(1,1,1),(1,1,2),(1,1,3),⋯]
  99. 99. 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)
  100. 100. Generators[ (a, b, c) | a <- nats, b <- [1..a], c <- [1..b]][(1,1,1),(2,1,1),(2,2,1),⋯]
  101. 101. Generators[ (a, b, c) | c <- nats, b <- [1..c], a <- [1..b]][(1,1,1),(1,1,2),(1,2,2),⋯]
  102. 102. 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),⋯]
  103. 103. 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),⋯]
  104. 104. 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),⋯]
  105. 105. 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),⋯]
  106. 106. Recursionprimes = sieve [2..] where sieve (p:xs) = p : sieve [x | x <- xs, rem x p /= 0]
  107. 107. Recursionprimes = sieve [2..] where sieve (p:xs) = p : sieve [x | x <- xs, rem x p /= 0]primes
  108. 108. Recursionprimes = sieve [2..] where sieve (p:xs) = p : sieve [x | x <- xs, rem x p /= 0]sieve [2..]
  109. 109. Recursionprimes = sieve [2..] where sieve (p:xs) = p : sieve [x | x <- xs, rem x p /= 0]sieve (2:[3..])
  110. 110. 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]
  111. 111. 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]
  112. 112. 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])
  113. 113. 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]
  114. 114. 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]
  115. 115. 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]
  116. 116. 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]
  117. 117. 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]
  118. 118. 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])
  119. 119. 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]
  120. 120. 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]
  121. 121. 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]
  122. 122. 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]
  123. 123. 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]
  124. 124. 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]
  125. 125. 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])
  126. 126. Recursionprimes = sieve [2..] where sieve (p:xs) = p : sieve [x | x <- xs, rem x p /= 0]2 : 3 : 5 : 7 : sieve ⋯
  127. 127. Recursionprimes = sieve [2..] where sieve (p:xs) = p : sieve [x | x <- xs, rem x p /= 0][2, 3, 5, 7, sieve ⋯]
  128. 128. To be continued...
  129. 129. SummaryHaskell has parametric types.List Comprehensions are cool.
  130. 130. Preview: Infinite Listsprimes = sieve [2..] where sieve (p:xs) = p : sieve [x | x <- xs, rem x p /= 0]
  131. 131. Preview: IO (echo.hs)import System.Environment (getArgs)import Data.List (intercalate)main = do args <- getArgs putStrLn (intercalate " " args)
  132. 132. Preview: Parsers
  133. 133. Preview: Parse JSONdata Value = String String | Number Double | Object [(String, Value)] | Array [Value] | Bool Bool | Null
  134. 134. Preview: Parse JSONvalue = String <$>jsstring <|> Number <$>number <|> Object <$>commaGroup { pair } <|> Array <$>commaGroup [ value ] <|> Bool True <$ string "true" <|> Bool False <$ string "false" <|> Null <$ string "null"
  135. 135. Preview: Parse JSONpair :: Parser (String, Value)pair = do s <- jsstring sp_char_sp : v <- value spaces return (s, v)
  136. 136. To be continued...

×