12/11/2013 CSCI-2325 More on Haskell Mohammad T . Irfan 12/4/13 Recap: list examples Prime numbers primes = primeGen' [2 ..] where primeGen' (p:xs) = p : primeGen' [q | q <- xs, mod q p /= 0] Getting the first 10 prime numbers take 10 primes Lazy evaluation Side note: This is not really the sieve of Eratosthenes http://www.cs.hmc.edu/~oneill/papers/Sieve-JFP .pdf 1
12/11/2013 How many numbers are crossed off? Haskell’s implementation of the take function and list comprehension/generation take n (x:xs) = x : take (n-1) xs Lambda calculus n-queens problem queens n = solve n where solve k | k <= 0 = [ [] ] | otherwise = [ h:partial | partial <- solve (k-1), h <- [0..(n-1)], safe h partial] safe h partial = and [ not ( checks h partial i) | i <- [0..(length partial - 1)]] checks h partial i = h == partial!!i || abs(h - partial!!i) == i+1 2
12/11/2013 Higher-order functions Function as a parameter Curried function Examples max 10 20 take 10 primes To visualize this :t max Haskell Curry 3 most useful built-in functions 1. map function list map ( > 0) [2, -50, 100] -- [True, False, True] Equivalent: [ x > 0 | x <- [2, -50, 100] ] map (`mod` 2) [13, 14, 15] -- [1, 0, 1] 2. filter predicate/condition list Sorting function (from last class) sort [] = [] sort (x:xs) = sort (filter (< x) xs) sort [b| b<-xs, b<x] ++ [x] ++ sort (filter (>= x) xs) 3
12/11/2013 3. Fold: produces single value from a list (From Haskell.org) f does not take a list as parameter foldl f z [] = z foldl f z (x:xs) = foldl f (f z x) xs foldr f z [] = z foldr f z (x:xs) = f x (foldr f z xs) Example anyTrue = foldr (||) False [True, True ..] anyTrue = foldl (||) False [True, True ..] Problem: Evaluate Polish prefix expression 10 + (15 – 5) * 4 + 10 * - 15 5 4 10 + 15 – 5 * 4 + 10 - 15 * 5 4 Input: String (list of characters) of Polish prefix expression Output: Value of expression Solution Reverse the expr foldl Traverse it from left to right Push and pop using a stack Implement stack by a list: TOS is head 4
12/11/2013 Solution import Data.List -- at the top evaluatePrefix expr = head ( foldl f [] ( reverse (words expr) ) ) where f (x:y:ys) "*" = (x*y):ys f (x:y:ys) "+" = (x+y):ys f (x:y:ys) "-" = (x-y):ys f xs str = read str:xs Problem: Finding the shortest path From Learn You a Haskell book 5
12/11/2013 Solution data Section = Section { getA :: Int, getB :: Int, getC :: Int } deriving (Show) type RoadSystem = [Section] heathrowToLondon :: RoadSystem heathrowToLondon = [Section 50 10 30, Section 5 90 20, Section 40 2 25, Section 10 8 0] data Label = A | B | C deriving (Show) type Path = [(Label, Int)] roadStep :: (Path, Path) -> Section -> (Path, Path) roadStep (pathA, pathB) (Section a b c) = let priceA = sum $ map snd pathA priceB = sum $ map snd pathB forwardPriceToA = priceA + a crossPriceToA = priceB + b + c forwardPriceToB = priceB + b crossPriceToB = priceA + a + c newPathToA = if forwardPriceToA <= crossPriceToA then (A,a):pathA else (C,c):(B,b):pathB newPathToB = if forwardPriceToB <= crossPriceToB then (B,b):pathB else (C,c):(A,a):pathA in (newPathToA, newPathToB) -- test it: roadStep ([], []) (head heathrowToLondon) 6
12/11/2013 optimalPath :: RoadSystem -> Path optimalPath roadSystem = let (bestAPath, bestBPath) = foldl roadStep ([],[]) roadSystem in if sum (map snd bestAPath) <= sum (map snd bestBPath) then reverse bestAPath else reverse bestBPath -- test it: optimalPath heathrowToLondon Lab Assignment Either one of the following two Implement a Sudoko solver using Haskell Research on infinite lists and lazy evaluation in imperative and object oriented programming languages Pointer: Functional thinking: Laziness, Part 1 Exploring lazy evaluation in Java by Neal Ford http://www.ibm.com/developerworks/opensource/lib rary/j-ft18/j-ft18-pdf.pdf 7
Recommend
More recommend