haskell tour (part 3)

168
Haskell A Whirlwind Tour (Part III) William Taysom ~ 2011

Upload: william-taysom

Post on 05-Sep-2014

965 views

Category:

Technology


2 download

DESCRIPTION

The exciting conclusion to our Haskell introduction. Today we talk about type classes, monads, a monadic parser combinators (e.g. Parsec) climaxing with an example JSON parser.

TRANSCRIPT

Page 1: Haskell Tour (Part 3)

HaskellA Whirlwind Tour

(Part III)William Taysom ~ 2011

Page 2: Haskell Tour (Part 3)
Page 3: Haskell Tour (Part 3)

Haskell is a non-strict, purely functional programming language with strong,static type inference.

Page 4: Haskell Tour (Part 3)

Review

Page 5: Haskell Tour (Part 3)

Recursive Data

data Color = Red | Green | Blue | Mix Color Color

Page 6: Haskell Tour (Part 3)

hue :: Color -> Maybe Doublehue Red = Just 0hue Green = Just 120hue Blue = Just 240

Recursive Functions

Page 7: Haskell Tour (Part 3)

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

Page 8: Haskell Tour (Part 3)

Parametric Data

data (a, b) = (a, b)data Either a b = Left a | Right bdata Maybe a = Nothing | Just adata [a] = [] | a:[a]

type String = [Char]

Page 9: Haskell Tour (Part 3)

Parametric Functions

(.) :: (b -> c) -> (a -> b) -> a -> cinfixr . -- defaults to 9(f . g) x = f (g x)

map :: (a -> b) -> [a] -> [b]map f [] = []map f (x:xs) = f x : map f xs

Page 10: Haskell Tour (Part 3)

List Comprehensions

primitivePythagoreanTriples = [ (a, b, c) | c <- nats, b <- [1..c], a <- [1..b], a^2 + b^2 == c^2, gcd a b == 1]

primes = sieve [2..] where sieve (p:xs) = p : sieve [x | x <- xs, rem x p /= 0]

Page 11: Haskell Tour (Part 3)

Type Classes

Page 12: Haskell Tour (Part 3)

Membership Test

infix 4 `elem`x `elem` xs = case filter (== x) xs of [] -> False _ -> True

'q' `elem` a_z --> True'8' `elem` a_z --> False

Page 13: Haskell Tour (Part 3)

Membership Test

elem :: a -> [a] -> Boolinfix 4 `elem`x `elem` xs = case filter (== x) xs of [] -> False _ -> True

'q' `elem` a_z --> True'8' `elem` a_z --> False

Page 14: Haskell Tour (Part 3)

Membership Test

elem :: a -> [a] -> Boolinfix 4 `elem`x `elem` xs = case filter (== x) xs of [] -> False _ -> True

'q' `elem` a_z --> True'8' `elem` a_z --> False

Page 15: Haskell Tour (Part 3)

Membership Test

elem :: a -> [a] -> Boolinfix 4 `elem`x `elem` xs = case filter (== x) xs of [] -> False _ -> True

'q' `elem` a_z --> True'8' `elem` a_z --> False

Page 16: Haskell Tour (Part 3)

Membership Test

elem :: a -> [a] -> Boolinfix 4 `elem`x `elem` xs = case filter (== x) xs of [] -> False _ -> True

'q' `elem` a_z --> True'8' `elem` a_z --> False

Page 17: Haskell Tour (Part 3)

Membership Test

elem :: a -> [a] -> Boolinfix 4 `elem`x `elem` xs = case filter (== x) xs of [] -> False _ -> True

'q' `elem` a_z --> True'8' `elem` a_z --> False

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

Page 18: Haskell Tour (Part 3)

Membership Test

elem :: a -> [a] -> Boolinfix 4 `elem`x `elem` xs = case filter (== x) xs of [] -> False _ -> True

'q' `elem` a_z --> True'8' `elem` a_z --> False

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

Page 19: Haskell Tour (Part 3)

Membership Test

elem :: a -> [a] -> Boolinfix 4 `elem`x `elem` xs = case filter (== x) xs of [] -> False _ -> True

'q' `elem` a_z --> True'8' `elem` a_z --> False

Page 20: Haskell Tour (Part 3)

Membership Test

elem :: Eq a => a -> [a] -> Boolinfix 4 `elem`x `elem` xs = case filter (== x) xs of [] -> False _ -> True

'q' `elem` a_z --> True'8' `elem` a_z --> False

Page 21: Haskell Tour (Part 3)

Membership Test

elem :: Eq a => a -> [a] -> Boolinfix 4 `elem`x `elem` xs = case filter (== x) xs of [] -> False _ -> True

'q' `elem` a_z --> True'8' `elem` a_z --> False

Page 22: Haskell Tour (Part 3)

Eq Instance

instance Eq Color where Red == Red = True Green == Green = True Blue == Blue = True Mix c c' == Mix d d' = c == d && c' == d' _ == _ = False

Page 23: Haskell Tour (Part 3)

instance Eq Color where Red == Red = True Green == Green = True Blue == Blue = True Mix c c' == Mix d d' = c == d && c' == d' _ == _ = False

Eq Instance

Page 24: Haskell Tour (Part 3)

instance Eq Color where Red == Red = True Green == Green = True Blue == Blue = True Mix c c' == Mix d d' = c == d && c' == d' _ == _ = False

Eq Instanceghci> :i Color

Page 25: Haskell Tour (Part 3)

ghci> :i Colordata Color = Red | Green | Blue | Mix Color Color !-- Defined at example.hs:1:6-10instance Eq Color -- Defined at example.hs:3:10-17ghci>

Page 26: Haskell Tour (Part 3)

ghci> :i Colordata Color = Red | Green | Blue | Mix Color Color !-- Defined at example.hs:1:6-10instance Eq Color -- Defined at example.hs:3:10-17ghci> :i Eq

Page 27: Haskell Tour (Part 3)

Default Definitions

class Eq a where (==), (/=) :: a -> a -> Bool x /= y = not (x == y) x == y = not (x /= y)

ghci> :i Colordata Color = Red | Green | Blue | Mix Color Color !-- Defined at example.hs:1:6-10instance Eq Color -- Defined at example.hs:3:10-17ghci> :i Eqclass Eq a where (==) :: a -> a -> Bool (/=) :: a -> a -> Bool !-- Defined in GHC.Classes... followed by 26 instances ...

Page 28: Haskell Tour (Part 3)

Default Definitions

class Eq a where (==), (/=) :: a -> a -> Bool x /= y = not (x == y) x == y = not (x /= y)

Page 29: Haskell Tour (Part 3)

Default Definitions

class Eq a where (==), (/=) :: a -> a -> Bool x /= y = not (x == y) x == y = not (x /= y)

Page 30: Haskell Tour (Part 3)

Default Definitions

class Eq a where (==), (/=) :: a -> a -> Bool x /= y = not (x == y) x == y = not (x /= y)

Page 31: Haskell Tour (Part 3)

Default Definitions

class Eq a where (==), (/=) :: a -> a -> Bool x /= y = not (x == y) x == y = not (x /= y)

ghci> :i Colordata Color = Red | Green | Blue | Mix Color Color !-- Defined at example.hs:1:6-10instance Eq Color -- Defined at example.hs:3:10-17ghci> :i Eqclass Eq a where (==) :: a -> a -> Bool (/=) :: a -> a -> Bool !-- Defined in GHC.Classes... followed by 26 instances ...

Page 32: Haskell Tour (Part 3)

... some Eq instances ...instance Eq Colorinstance Eq Boolinstance Eq Char

Page 33: Haskell Tour (Part 3)

... some Eq instances ...instance Eq Colorinstance Eq Boolinstance Eq Char

instance Eq a => Eq [a]instance (Eq a, Eq b) => Eq (a, b)

Page 34: Haskell Tour (Part 3)

ghci> :t compare

Page 35: Haskell Tour (Part 3)

ghci> :t comparecompare :: Ord a => a -> a -> Orderingghci>

Page 36: Haskell Tour (Part 3)

ghci> :t comparecompare :: Ord a => a -> a -> Orderingghci> :i Ord

Page 37: Haskell Tour (Part 3)

instance Ord Color where Red <= _ = True Green <= Red = False Green <= _ = True Blue <= Red = False Blue <= Green = False Blue <= _ = True Mix c c' <= Mix d d' | c == d = c' <= d' | otherwise = c <= d _ <= _ = False

Ord Instanceghci> :t comparecompare :: Ord a => a -> a -> Orderingghci> :i Ordclass Eq a => Ord a where! compare :: a -> a -> Ordering! (<) :: a -> a -> Bool! (>=) :: a -> a -> Bool! (>) :: a -> a -> Bool! (<=) :: a -> a -> Bool! max :: a -> a -> a! min :: a -> a -> a -- Defined in GHC.Classes

Page 38: Haskell Tour (Part 3)

instance Ord Color where Red <= _ = True Green <= Red = False Green <= _ = True Blue <= Red = False Blue <= Green = False Blue <= _ = True Mix c c' <= Mix d d' | c == d = c' <= d' | otherwise = c <= d _ <= _ = False

Ord Instance

Page 39: Haskell Tour (Part 3)

instance Ord Color where Red <= _ = True Green <= Red = False Green <= _ = True Blue <= Red = False Blue <= Green = False Blue <= _ = True Mix c c' <= Mix d d' | c == d = c' <= d' | otherwise = c <= d _ <= _ = False

Ord Instance

Page 40: Haskell Tour (Part 3)

Derived Instances

data Color = Red | Green | Blue | Mix Color Color deriving (Eq, Ord, Read, Show)

Page 41: Haskell Tour (Part 3)

Derived Instances

data Color = Red | Green | Blue | Mix Color Color deriving (Eq, Ord, Read, Show)

Page 42: Haskell Tour (Part 3)

Derived Instances

data Color = Red | Green | Blue | Mix Color Color deriving (Eq, Ord, Read, Show)

ghci> show (Mix Red Green)

Page 43: Haskell Tour (Part 3)

ghci> show (Mix Red Green)"Mix Red Green"ghci>

Page 44: Haskell Tour (Part 3)

ghci> show (Mix Red Green)"Mix Red Green"ghci> read "Mix Red Green"

Page 45: Haskell Tour (Part 3)

ghci> show (Mix Red Green)"Mix Red Green"ghci> read "Mix Red Green"<interactive>:1:1: Ambiguous type variable `a0' in the constraint: (Read a0) arising from a use of `read' Probable fix: add a type signature that fixes these type variable(s) In the expression: read "Mix Red Green" In an equation for `it': it = read "Mix Red Green"

Page 46: Haskell Tour (Part 3)

ghci> show (Mix Red Green)"Mix Red Green"ghci> read "Mix Red Green"<interactive>:1:1: Ambiguous type variable `a0' in the constraint: (Read a0) arising from a use of `read' Probable fix: add a type signature that fixes these type variable(s) In the expression: read "Mix Red Green" In an equation for `it': it = read "Mix Red Green"

Page 47: Haskell Tour (Part 3)

ghci> show (Mix Red Green)"Mix Red Green"ghci> read "Mix Red Green"<interactive>:1:1: Ambiguous type variable `a0' in the constraint: (Read a0) arising from a use of `read' Probable fix: add a type signature that fixes these type variable(s) In the expression: read "Mix Red Green" In an equation for `it': it = read "Mix Red Green"

Page 48: Haskell Tour (Part 3)
Page 49: Haskell Tour (Part 3)

ghci> :t read

Page 50: Haskell Tour (Part 3)

ghci> :t readread :: Read a => String -> aghci>

Page 51: Haskell Tour (Part 3)

ghci> :t readread :: Read a => String -> aghci> hue (read "Mix Red Green")

Page 52: Haskell Tour (Part 3)

ghci> :t readread :: Read a => String -> aghci> hue (read "Mix Red Green")60.0ghci>

Page 53: Haskell Tour (Part 3)

ghci> :t readread :: Read a => String -> aghci> hue (read "Mix Red Green")60.0ghci> read "Mix Red Green"

Page 54: Haskell Tour (Part 3)

ghci> :t readread :: Read a => String -> aghci> hue (read "Mix Red Green")60.0ghci> read "Mix Red Green" :: Color

Page 55: Haskell Tour (Part 3)

Type Classes Comparedghci> :t readread :: Read a => String -> aghci> hue (read "Mix Red Green")60.0ghci> read "Mix Red Green" :: ColorMix Red Greenghci>

Page 56: Haskell Tour (Part 3)

Type Classes Compared

Page 57: Haskell Tour (Part 3)

Type Classes Compared

Page 58: Haskell Tour (Part 3)

Type Classes Compared

OO Class Type Class

Instance Object Type(Not Value)

Dispatch Dynamic on Receiver

Static on Any Part(Like Overloading)

Extension Subclassing Class Conditions(No Subtypes)

Reuse Inheritance Default(No Overriding)

Page 59: Haskell Tour (Part 3)

Type Classes Compared

OO Class Type Class

Instance Object Type(Not Value)

Dispatch Dynamic on Receiver

Static on Any Part(Like Overloading)

Extension Subclassing Class Conditions(No Subtypes)

Reuse Inheritance Default(No Overriding)

Page 60: Haskell Tour (Part 3)

Type Classes Compared

OO Class Type Class

Instance Object Type(Not Value)

Dispatch Dynamic on Receiver

Static on Any Part(Like Overloading)

Extension Subclassing Class Conditions(No Subtypes)

Reuse Inheritance Default(No Overriding)

Page 61: Haskell Tour (Part 3)

Type Classes Compared

OO Class Type Class

Instance Object Type(Not Value)

Dispatch Dynamic on Receiver

Static on Any Part(Like Overloading)

Extension Subclassing Class Conditions(No Subtypes)

Reuse Inheritance Default(No Overriding)

Page 62: Haskell Tour (Part 3)

Type Classes Compared

OO Class Type Class

Instance Object Type(Not Value)

Dispatch Dynamic on Receiver

Static on Any Part(Like Overloading)

Extension Subclassing Class Conditions(No Subtypes)

Reuse Inheritance Default(No Overriding)

Page 63: Haskell Tour (Part 3)

Type Classes Compared

OO Class Type Class

Instance Object Type(Not Value)

Dispatch Dynamic on Receiver

Static on Any Part(Like Overloading)

Extension Subclassing Class Conditions(No Subtypes)

Reuse Inheritance Default(No Overriding)

Page 64: Haskell Tour (Part 3)

Type Classes Compared

OO Class Type Class

Instance Object Type(Not Value)

Dispatch Dynamic on Receiver

Static on Any Part(Like Overloading)

Extension Subclassing Class Conditions(No Subtypes)

Reuse Inheritance Default(No Overriding)

Page 65: Haskell Tour (Part 3)

Type Classes Compared

OO Class Type Class

Instance Object Type(Not Value)

Dispatch Dynamic on Receiver

Static on Any Part(Like Overloading)

Extension Subclassing Class Conditions(No Subtypes)

Reuse Inheritance Default(No Overriding)

Page 66: Haskell Tour (Part 3)

Type Classes Compared

OO Class Type Class

Instance Object Type(Not Value)

Dispatch Dynamic on Receiver

Static on Any Part(Like Overloading)

Extension Subclassing Class Conditions(No Subtypes)

Reuse Inheritance Default(No Overriding)

Page 67: Haskell Tour (Part 3)
Page 68: Haskell Tour (Part 3)
Page 69: Haskell Tour (Part 3)
Page 70: Haskell Tour (Part 3)

intFromHexString :: String -> IntintFromHexString [] = 0intFromHexString (c:cs) = digitToInt c * 16 ^ length cs + intFromHexString cs

Page 71: Haskell Tour (Part 3)

numberFromString :: Num a => String -> anumberFromString [] = 0numberFromString (c:cs) = fromIntegral (digitToInt c) * 10 ^ fromIntegral (length cs) + integerFromString cs

Page 72: Haskell Tour (Part 3)

numberFromString :: Num a => String -> anumberFromString [] = 0numberFromString (c:cs) = fromIntegral (digitToInt c) * 10 ^ fromIntegral (length cs) + integerFromString cs

fromIntegral :: (Num b, Integral a) => a -> b

Page 73: Haskell Tour (Part 3)
Page 74: Haskell Tour (Part 3)
Page 75: Haskell Tour (Part 3)

Monads

Page 76: Haskell Tour (Part 3)

Monad Class

class Monad m where return :: a -> m a (>>=) :: m a -> (a -> m b) -> m b (>>) :: m a -> m b -> m b m >> n = m >>= \_ -> n

Page 77: Haskell Tour (Part 3)

Maybe (Failure)

instance Monad Maybe where return = Just Nothing >>= k = Nothing Just x >>= k = k x

Page 78: Haskell Tour (Part 3)

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

Page 79: Haskell Tour (Part 3)

hue (Mix c c') = case (hue c, hue c') of (Just h, Just h') -> ... _ -> Nothing

Page 80: Haskell Tour (Part 3)

hue (Mix c c') = case hue c of Just h -> case hue c' of Just h' -> ... Nothing -> Nothing Nothing -> Nothing

Page 81: Haskell Tour (Part 3)

hue (Mix c c') = case hue c of Just h -> hue c' >>= \h' -> ... Nothing -> Nothing

Page 82: Haskell Tour (Part 3)

hue (Mix c c') = hue c >>= \h -> hue c' >>= \h' -> ...

Page 83: Haskell Tour (Part 3)

hue (Mix c c') = hue c >>= \h -> do h' <- hue c'; ...

Page 84: Haskell Tour (Part 3)

hue (Mix c c') = do h <- hue c do h' <- hue c'; ...

Page 85: Haskell Tour (Part 3)

hue (Mix c c') = do h <- hue c h' <- hue c' ...

Page 86: Haskell Tour (Part 3)

hue (Mix c c') = do h <- hue c h' <- hue c' 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'

Page 87: Haskell Tour (Part 3)

hue (Mix c c') = do h <- hue c h' <- hue c' let m = average h h' m' = norm (m + 180) d = distance h m case compare d 90 of LT -> Just m EQ -> Nothing GT -> Just m'

Page 88: Haskell Tour (Part 3)

instance Monad [] where return x = [x] xs >>= k = concat (map k xs)

List (Nondeterminism)

Page 89: Haskell Tour (Part 3)

[ (a, b, c) | c <- nats, b <- [1..c], a <- [1..b]]

Page 90: Haskell Tour (Part 3)

[ (a, b, c) | c <- nats, b <- [1..c], a <- [1..b]]

do c <- nats b <- [1..c] a <- [1..b] return (a, b, c)

Page 91: Haskell Tour (Part 3)

(<$>) :: Monad m => (a -> b) -> m a -> m bf <$> m = m >>= return . f

ord <$> "abc" --> [97, 98, 99]

Generalized Map

Page 92: Haskell Tour (Part 3)

Constant Map

(<$) :: Monad m => a -> m b -> m a(<$) = (<$>) . const

'x' <$ "abc" --> "xxx"

Page 93: Haskell Tour (Part 3)

[ (a, b, c) | c <- nats, b <- [1..c], a <- [1..b]]

do c <- nats b <- [1..c] a <- [1..b] return (a, b, c)

Page 94: Haskell Tour (Part 3)

[ (a, b, c) | c <- nats, b <- [1..c], a <- [1..b], a^2 + b^2 == c^2]

do c <- nats b <- [1..c] a <- [1..b] guard $ a^2 + b^2 == c^2 return (a, b, c)

Page 95: Haskell Tour (Part 3)

class Monad m => MonadPlus m where mzero :: m a mplus :: m a -> m a -> m a

MonadPlus Class

Page 96: Haskell Tour (Part 3)

instance MonadPlus [] where mzero = [] mplus = (++)

List (Nondeterminism)

Page 97: Haskell Tour (Part 3)

Guard

guard :: MonadPlus m => Bool -> m ()guard True = return ()guard False = mzero

Page 98: Haskell Tour (Part 3)

Getter

data Getter a = Getter (String -> (a, String))

get :: Getter a -> String -> (a, String)get (Getter g) = g

Page 99: Haskell Tour (Part 3)

Getter

instance Monad Getter where return x = Getter $ \s -> (x, s) g >>= k = Getter $ \s -> let (x, s') = get g s in get (k x) s'

Page 100: Haskell Tour (Part 3)

Primitive Action

getChar :: Getter ChargetChar = Getter $ \s -> case s of c:cs -> (c , cs) "" -> ('\0', "")

Page 101: Haskell Tour (Part 3)

Derived Action

getLine :: Getter StringgetLine = do c <- getChar if c == '\n' || c == '\0' then return "" else do s <- getLine return $ c:s

get getLine "hello\nworld" --> ("hello", "world")

Page 102: Haskell Tour (Part 3)

IO

data IO a = IO (RealWorld -> (a, RealWorld))

putChar :: Char -> IO ()

Page 103: Haskell Tour (Part 3)

Print Functions

putStr :: String -> IO ()putStr "" = return ()putStr (c:cs) = do putChar c putStr cs

Page 104: Haskell Tour (Part 3)

Print Functions

putStrLn :: String -> IO ()putStrLn s = do putStr s putChar '\n'

Page 105: Haskell Tour (Part 3)

Main Point

“The business of the program is to construct one gianormous action which is then performed.”

— Simon Peyton-Jones

Page 106: Haskell Tour (Part 3)

hello.hs

main = putStrLn "hello, world"

Page 107: Haskell Tour (Part 3)

Parsers

Page 108: Haskell Tour (Part 3)

Parsers

Page 109: Haskell Tour (Part 3)

Parsers

data Parser a = Parser (String -> [(a, String)])

parse :: Parser a -> String -> [(a, String)]parse (Parser p) = p

Page 110: Haskell Tour (Part 3)

Parsers

instance Monad Parser where return x = Parser $ \s -> [(x, s)] p >>= k = Parser $ \s -> concat [parse (k x) s' | (x, s') <- parse p s]

Page 111: Haskell Tour (Part 3)

Parsers

instance MonadPlus Parser where mzero = Parser $ \s -> [] mplus p q = Parser $ \s -> parse p s ++ parse q s

Page 112: Haskell Tour (Part 3)

Parsers

instance MonadPlus Parser where mzero = Parser $ \s -> [] mplus p q = Parser $ \s -> parse p s ++ parse q s

(<|>) :: Parser a -> Parser a -> Parser ainfixr 1 <|>(<|>) = mplus

Page 113: Haskell Tour (Part 3)

Primitive Actions

anyChar :: Parser CharanyChar = Parser $ \s -> case s of c:cs -> [(c, cs)] "" -> []

eof :: Parser ()eof = Parser $ \s -> case s of c:cs -> [] "" -> [((), "")]

Page 114: Haskell Tour (Part 3)

Derived Actions

satisfy :: (Char -> Bool) -> Parser Charsatisfy f = do c <- anyChar if f c then return c else mzero

Page 115: Haskell Tour (Part 3)

Derived Actions

char :: Char -> Parser Charchar c = satisfy (== c)

Page 116: Haskell Tour (Part 3)

Derived Actions

string :: String -> Parser Stringstring "" = return ""string s@(c:cs) = do char c string cs return s

Page 117: Haskell Tour (Part 3)

Backtracking

hiHeHello = string "hi" <|> string "he" <|> string "hello"

Page 118: Haskell Tour (Part 3)

Backtracking

hiHeHello = string "hi" <|> string "he" <|> string "hello"

parse hiHeHello "hello" --> [("he","llo"), ("hello","")]

Page 119: Haskell Tour (Part 3)

Parsec

type Parser = Parsec String ()

Page 120: Haskell Tour (Part 3)

Parsec

type Parser = Parsec String ()

hiHeHello = string "hi" <|> string "he" <|> string "hello"

parseTest hiHeHello "hello" >>-> unexpected "e" expecting "hi"

Page 121: Haskell Tour (Part 3)

Optional Backtracking

try :: Parser a -> Parser a

Page 122: Haskell Tour (Part 3)

Optional Backtracking

try :: Parser a -> Parser a

hiHeHello' = try (string "hi") <|> string "he" <|> string "hello"

Page 123: Haskell Tour (Part 3)

Optional Backtracking

try :: Parser a -> Parser a

hiHeHello' = try (string "hi") <|> string "he" <|> string "hello"

parseTest hiHeHello' "hello" >>-> "he"

Page 124: Haskell Tour (Part 3)

Error Messages

(<?>) :: Parser a -> String -> Parser a

Page 125: Haskell Tour (Part 3)

Error Messages

(<?>) :: Parser a -> String -> Parser a

space :: Parser Charspace = satisfy isSpace <?> "space"

digit :: Parser Chardigit = satisfy isDigit <?> "digit"

hexDigit :: Parser CharhexDigit = satisfy isHexDigit <?> "hexadecimal digit"

Page 126: Haskell Tour (Part 3)

Error Messages

parseTest (space <|> digit <|> hexDigit) "hello" >>-> unexpected "h" expecting space, digit or hexadecimal digit

Page 127: Haskell Tour (Part 3)

Parser Combinators

oneOf :: String -> Parser Char

-- ExampleeE = oneOf "eE"

Page 128: Haskell Tour (Part 3)

Parser Combinators

noneOf :: String -> Parser Char

-- ExamplenotDoubleQuote = noneOf "\""

Page 129: Haskell Tour (Part 3)

Parser Combinators

between :: Parser a -> Parser b -> Parser c -> Parser c

-- Definitionbetween open close p = do open x <- p close return x

Page 130: Haskell Tour (Part 3)

Parser Combinators

option :: a -> Parser a -> Parser a

-- Definitionoption x p = p <|> return x

Page 131: Haskell Tour (Part 3)

Parser Combinators

count :: Int -> Parser a -> Parser [a]

-- ExamplehexDigit4 = count 4 hexDigit

Page 132: Haskell Tour (Part 3)

Parser Combinators

many, many1 :: Parser a -> Parser [a]

-- Exampledigits = many1 digit

Page 133: Haskell Tour (Part 3)

Parser Combinators

skipMany :: Parser a -> Parser ()

-- ExampleskipMany p = many p >> return ()

Page 134: Haskell Tour (Part 3)

Parser Combinators

spaces :: Parser ()

-- Definitionspaces = skipMany space

Page 135: Haskell Tour (Part 3)

Parser Combinators

sepBy :: Parser a -> Parser b -> Parser [a]

-- Examplewords = (many1 . satisfy) (not . isSpace) `sepBy` spaces

Page 136: Haskell Tour (Part 3)

Space Management

justOne :: Parser a -> Parser ajustOne = between spaces (spaces >> eof)

Page 137: Haskell Tour (Part 3)

Space Management

char_sp :: Char -> Parser ()char_sp c = do char c spaces

sp_char_sp :: Char -> Parser ()sp_char_sp c = do spaces char_sp c

Page 138: Haskell Tour (Part 3)

Space Management

commaGroup :: Char -> Parser a -> Char -> Parser [a]

commaGroup open item close = between (char_sp open) (sp_char_sp close) $ item `sepBy` sp_char_sp ','

Page 139: Haskell Tour (Part 3)

Parse String

Page 140: Haskell Tour (Part 3)

Parse String

jsstring :: Parser Stringjsstring = between doubleQuote doubleQuote $ many character

Page 141: Haskell Tour (Part 3)

Parse String

jsstring :: Parser Stringjsstring = between doubleQuote doubleQuote $ many character

doubleQuote :: Parser ChardoubleQuote = char '"'

Page 142: Haskell Tour (Part 3)

Parse String

jsstring :: Parser Stringjsstring = between doubleQuote doubleQuote $ many character

doubleQuote :: Parser ChardoubleQuote = char '"'

character :: Parser Charcharacter = (char '\\' >> escapeChar) <|> notDoubleQuote

Page 143: Haskell Tour (Part 3)

escapeChar :: Parser CharescapeChar = char '"' <|> char '\\' <|> char '/' <|> '\b' <$ char 'b' <|> '\f' <$ char 'f' <|> '\n' <$ char 'n' <|> '\r' <$ char 'r' <|> '\t' <$ char 't' <|> unicode

Page 144: Haskell Tour (Part 3)

unicode :: Parser Charunicode = do char 'u' digits <- hexDigit4 let n = intFromHexString digits return $ chr n

Page 145: Haskell Tour (Part 3)

Parse Number

Page 146: Haskell Tour (Part 3)

Parse Number

number :: Parser Doublenumber = do s <- sign n <- int f <- frac e <- expon return $ s * (n + f) * e

Page 147: Haskell Tour (Part 3)

sign :: Parser Doublesign = option 1 $ (-1) <$ char '-'

int :: Parser Doubleint = 0 <$ char '0' <|> numberFromString <$> digits

Page 148: Haskell Tour (Part 3)

frac :: Parser Doublefrac = option 0 $ do char '.' n <- digits return $ numberFromString n / 10 ^^ length n

expon :: Parser Doubleexpon = option 1 $ do eE s <- sign n <- digits return $ s * 10 ** numberFromString n

Page 149: Haskell Tour (Part 3)

Parse JSON

Page 150: Haskell Tour (Part 3)

Parse JSON

Page 151: Haskell Tour (Part 3)

Parse JSON

Page 152: Haskell Tour (Part 3)

data Value = String String | Number Double | Object [(String, Value)] | Array [Value] | Bool Bool

| Null

Parse JSON

Page 153: Haskell Tour (Part 3)

value = String <$> jsstring <|> Number <$> number <|> Object <$> commaGroup '{' pair '}' <|> Array <$> commaGroup '[' value ']' <|> Bool True <$ string "true" <|> Bool False <$ string "false" <|> Null <$ string "null"

Parse JSON

Page 154: Haskell Tour (Part 3)

data Value = String String | Number Double | Object [(String, Value)] | Array [Value] | Bool Bool

| Null

Parse JSON

Page 155: Haskell Tour (Part 3)

value = String <$> jsstring <|> Number <$> number <|> Object <$> commaGroup '{' pair '}' <|> Array <$> commaGroup '[' value ']' <|> Bool True <$ string "true" <|> Bool False <$ string "false" <|> Null <$ string "null"

Parse JSON

Page 156: Haskell Tour (Part 3)

pair :: Parser (String, Value)pair = do s <- jsstring sp_char_sp ':' v <- value spaces return (s, v)

Page 157: Haskell Tour (Part 3)

parseJSON :: String -> ValueparseJSON s = case parse (justOne value) "" s of Left err -> error $ "JSON parse error " ++ show err Right v -> v

Page 158: Haskell Tour (Part 3)

parseJSON "{\"just\": [\"some\", 4, \"\\u24E4\"]}" --> Object [("just", Array [String "some", Number 4.0, String "\9444"])]

Page 159: Haskell Tour (Part 3)

parseJSON "{\"just\": [\"some\", 4, \"\\u24E4\"]}" --> Object [("just", Array [String "some", Number 4.0, String "\9444"])]

parseJSON "{\"just\": [\"some\", 4 \"\\u24E4\"]}" >>-> *** Exception: JSON parse error (line 1, column 21): unexpected "\"" expecting space or ","

Page 160: Haskell Tour (Part 3)

Summary

Page 161: Haskell Tour (Part 3)

Summary

Page 162: Haskell Tour (Part 3)

Summary

Parsers

Monads

Type Classes

Parametric Types

Functions and Data Types

Page 163: Haskell Tour (Part 3)

Summary

Parsers

Monads

Type Classes

Parametric Types

Functions and Data Types

Page 164: Haskell Tour (Part 3)

Summary

Parsers

Monads

Type Classes

Parametric Types

Functions and Data Types

Page 165: Haskell Tour (Part 3)

Summary

Parsers

Monads

Type Classes

Parametric Types

Functions and Data Types

Page 166: Haskell Tour (Part 3)

Summary

Parsers

Monads

Type Classes

Parametric Types

Functions and Data Types

Page 167: Haskell Tour (Part 3)

Haskell is a non-strict, purely functional programming language with strong,static type inference.

Page 168: Haskell Tour (Part 3)

Thank You