Upcoming SlideShare
×

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
8 Likes
Statistics
Notes
• Full Name
Comment goes here.

Are you sure you want to Yes No
• Be the first to comment

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

No notes for slide

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...