CS 457/557: Functional Languages - Computer Action...
Transcript of CS 457/557: Functional Languages - Computer Action...
![Page 1: CS 457/557: Functional Languages - Computer Action Teamweb.cecs.pdx.edu/~sheard/course/CS457-557/Notes/Laziness.pdf · 1 CS 457/557: Functional Languages Leveraging Laziness Mark](https://reader033.fdocuments.net/reader033/viewer/2022042404/5f19389d1438d900191d7cf6/html5/thumbnails/1.jpg)
1
CS 457/557: Functional Languages
Leveraging Laziness
Mark P Jones
Portland State University
![Page 2: CS 457/557: Functional Languages - Computer Action Teamweb.cecs.pdx.edu/~sheard/course/CS457-557/Notes/Laziness.pdf · 1 CS 457/557: Functional Languages Leveraging Laziness Mark](https://reader033.fdocuments.net/reader033/viewer/2022042404/5f19389d1438d900191d7cf6/html5/thumbnails/2.jpg)
Lazy Evaluation:
With a lazy evaluation strategy:
–! Don’t evaluate until you have to
–! When you do evaluate, save the result so that you can use it again next time …
Why use lazy evaluation?
–! Avoids redundant computation
–! Eliminates special cases (e.g., && and ||)
–! Facilitates reasoning
Lazy evaluation encourages:
–! Programming in a compositional style
–! Working with “infinite data structures”
–! Computing with “circular programs”
![Page 3: CS 457/557: Functional Languages - Computer Action Teamweb.cecs.pdx.edu/~sheard/course/CS457-557/Notes/Laziness.pdf · 1 CS 457/557: Functional Languages Leveraging Laziness Mark](https://reader033.fdocuments.net/reader033/viewer/2022042404/5f19389d1438d900191d7cf6/html5/thumbnails/3.jpg)
Compositional Style:
Separate aspects of program behavior separated into independent components
fact n = product [1..n]
sumSqrs n = sum (map (\x -> x*x) [1..n])
minimum = head . sort
![Page 4: CS 457/557: Functional Languages - Computer Action Teamweb.cecs.pdx.edu/~sheard/course/CS457-557/Notes/Laziness.pdf · 1 CS 457/557: Functional Languages Leveraging Laziness Mark](https://reader033.fdocuments.net/reader033/viewer/2022042404/5f19389d1438d900191d7cf6/html5/thumbnails/4.jpg)
“Infinite” Data Structures:
Data structures are evaluated lazily, so we can specify “infinite” data structures in which only the
parts that are actually needed are evaluated:
powersOfTwo = iterate (2*) 1
twoPow n = powersOfTwo !! n
fibs = 0 : 1 : zipWith (+) fibs (tail fibs)
fib n = fibs !! n
![Page 5: CS 457/557: Functional Languages - Computer Action Teamweb.cecs.pdx.edu/~sheard/course/CS457-557/Notes/Laziness.pdf · 1 CS 457/557: Functional Languages Leveraging Laziness Mark](https://reader033.fdocuments.net/reader033/viewer/2022042404/5f19389d1438d900191d7cf6/html5/thumbnails/5.jpg)
Circular Programs:
An example due to Richard Bird (“Using circular programs to eliminate multiple traversals of data”):
Consider a tree datatype: data Tree = Leaf | Fork Int Tree Tree
Define a function
repMin :: Tree -> Tree
that will produce an output tree with the same shape as the input but replacing each integer with the minimum value in the original tree.
![Page 6: CS 457/557: Functional Languages - Computer Action Teamweb.cecs.pdx.edu/~sheard/course/CS457-557/Notes/Laziness.pdf · 1 CS 457/557: Functional Languages Leveraging Laziness Mark](https://reader033.fdocuments.net/reader033/viewer/2022042404/5f19389d1438d900191d7cf6/html5/thumbnails/6.jpg)
Example:
Same shape, values replaced with minimum
4
2 3
9
6 1
5
7
1
1 1
1
1 1
1
1
repMin
![Page 7: CS 457/557: Functional Languages - Computer Action Teamweb.cecs.pdx.edu/~sheard/course/CS457-557/Notes/Laziness.pdf · 1 CS 457/557: Functional Languages Leveraging Laziness Mark](https://reader033.fdocuments.net/reader033/viewer/2022042404/5f19389d1438d900191d7cf6/html5/thumbnails/7.jpg)
Example:
Obvious implementation:
repMin t = mapTree (\n -> m) t
where m = minTree t
4
2 3
9
6 1
5
7
1
1 1
1
1 1
1
1
repMin
![Page 8: CS 457/557: Functional Languages - Computer Action Teamweb.cecs.pdx.edu/~sheard/course/CS457-557/Notes/Laziness.pdf · 1 CS 457/557: Functional Languages Leveraging Laziness Mark](https://reader033.fdocuments.net/reader033/viewer/2022042404/5f19389d1438d900191d7cf6/html5/thumbnails/8.jpg)
Example:
Can we do this with only one traversal?
4
2 3
9
6 1
5
7
1
1 1
1
1 1
1
1
repMin
![Page 9: CS 457/557: Functional Languages - Computer Action Teamweb.cecs.pdx.edu/~sheard/course/CS457-557/Notes/Laziness.pdf · 1 CS 457/557: Functional Languages Leveraging Laziness Mark](https://reader033.fdocuments.net/reader033/viewer/2022042404/5f19389d1438d900191d7cf6/html5/thumbnails/9.jpg)
A Slightly Easier Problem:
In a single traversal:
•! Calculate the minimum value in the tree
•! Replace each entry with some given n
4
2 3
9
6 1
5
7
n
n n
n
n n
n
n
repMin’ n ( 1, )
![Page 10: CS 457/557: Functional Languages - Computer Action Teamweb.cecs.pdx.edu/~sheard/course/CS457-557/Notes/Laziness.pdf · 1 CS 457/557: Functional Languages Leveraging Laziness Mark](https://reader033.fdocuments.net/reader033/viewer/2022042404/5f19389d1438d900191d7cf6/html5/thumbnails/10.jpg)
A Single Traversal:
We can code this algorithm fairly easily:
repMin’ :: Int -> Tree -> (Int, Tree)
repMin’ n Leaf = (maxInt, Leaf)
repMin’ n (Fork m l r)
= (min nl nr, Fork n l’ r’) where
(nl, l’) = repMin’ n l
(nr, r’) = repMin’ n r
![Page 11: CS 457/557: Functional Languages - Computer Action Teamweb.cecs.pdx.edu/~sheard/course/CS457-557/Notes/Laziness.pdf · 1 CS 457/557: Functional Languages Leveraging Laziness Mark](https://reader033.fdocuments.net/reader033/viewer/2022042404/5f19389d1438d900191d7cf6/html5/thumbnails/11.jpg)
“Tying the knot”
•! Now a call repMin’ m t will produce a pair (n, t’) where
–! n is the minimum value of all the integers in t
–! t’ is a tree with the same shape as t but with each integer replaced by m.
•! We can implement repMin by creating a cyclic structure that passes the minimum value that is returned by repMin’ as its first argument:
repMin t = t’ where (n, t’) = repMin’ n t
![Page 12: CS 457/557: Functional Languages - Computer Action Teamweb.cecs.pdx.edu/~sheard/course/CS457-557/Notes/Laziness.pdf · 1 CS 457/557: Functional Languages Leveraging Laziness Mark](https://reader033.fdocuments.net/reader033/viewer/2022042404/5f19389d1438d900191d7cf6/html5/thumbnails/12.jpg)
Aligning Separators: a more realistic
example
![Page 13: CS 457/557: Functional Languages - Computer Action Teamweb.cecs.pdx.edu/~sheard/course/CS457-557/Notes/Laziness.pdf · 1 CS 457/557: Functional Languages Leveraging Laziness Mark](https://reader033.fdocuments.net/reader033/viewer/2022042404/5f19389d1438d900191d7cf6/html5/thumbnails/13.jpg)
Mark is Fussy about Layout:
Have you noticed how I get fussy about code like:
map :: (a -> b) -> [a] -> [b]
map f [] = []
map f (x:xs) = f x : map f xs
filter :: (a -> Bool) -> [a] -> [a]
filter p [] = []
filter p (x:xs)
| p x = x : filter p xs
| otherwise = filter p xs
Mark
![Page 14: CS 457/557: Functional Languages - Computer Action Teamweb.cecs.pdx.edu/~sheard/course/CS457-557/Notes/Laziness.pdf · 1 CS 457/557: Functional Languages Leveraging Laziness Mark](https://reader033.fdocuments.net/reader033/viewer/2022042404/5f19389d1438d900191d7cf6/html5/thumbnails/14.jpg)
Mark is Fussy about Layout:
… and try to line up the separators like this:
map :: (a -> b) -> [a] -> [b]
map f [] = []
map f (x:xs) = f x : map f xs
filter :: (a -> Bool) -> [a] -> [a]
filter p [] = []
filter p (x:xs)
| p x = x : filter p xs
| otherwise = filter p xs
Mark
![Page 15: CS 457/557: Functional Languages - Computer Action Teamweb.cecs.pdx.edu/~sheard/course/CS457-557/Notes/Laziness.pdf · 1 CS 457/557: Functional Languages Leveraging Laziness Mark](https://reader033.fdocuments.net/reader033/viewer/2022042404/5f19389d1438d900191d7cf6/html5/thumbnails/15.jpg)
Can we do this Automatically?
map :: (a -> b) -> [a] -> [b]
map f [] = []
map f (x:xs) = f x : map f xs
filter :: (a -> Bool) -> [a] -> [a]
filter p [] = []
filter p (x:xs)
| p x = x : filter p xs
| otherwise = filter p xs
map :: (a -> b) -> [a] -> [b]
map f [] = []
map f (x:xs) = f x : map f xs
filter :: (a -> Bool) -> [a] -> [a]
filter p [] = []
filter p (x:xs)
| p x = x : filter p xs
| otherwise = filter p xs
![Page 16: CS 457/557: Functional Languages - Computer Action Teamweb.cecs.pdx.edu/~sheard/course/CS457-557/Notes/Laziness.pdf · 1 CS 457/557: Functional Languages Leveraging Laziness Mark](https://reader033.fdocuments.net/reader033/viewer/2022042404/5f19389d1438d900191d7cf6/html5/thumbnails/16.jpg)
Thinking about an Algorithm:
Let’s look at this line by line:
map :: (a -> b) -> [a] -> [b]
map f [] = []
map f (x:xs) = f x : map f xs
filter :: (a -> Bool) -> [a] -> [a]
filter p [] = []
filter p (x:xs)
| p x = x : filter p xs
| otherwise = filter p xs
6
10
14
9
13
10
16
Total # chars up to and including first separator Maximum
![Page 17: CS 457/557: Functional Languages - Computer Action Teamweb.cecs.pdx.edu/~sheard/course/CS457-557/Notes/Laziness.pdf · 1 CS 457/557: Functional Languages Leveraging Laziness Mark](https://reader033.fdocuments.net/reader033/viewer/2022042404/5f19389d1438d900191d7cf6/html5/thumbnails/17.jpg)
Thinking about an Algorithm:
Let’s look at this line by line:
map :: (a -> b) -> [a] -> [b]
map f [] = []
map f (x:xs) = f x : map f xs
filter :: (a -> Bool) -> [a] -> [a]
filter p [] = []
filter p (x:xs)
| p x = x : filter p xs
| otherwise = filter p xs
10
6
2
7
3
0
6
0
0
# extra chars to insert before first separator
6
10
14
9
13
10
16
![Page 18: CS 457/557: Functional Languages - Computer Action Teamweb.cecs.pdx.edu/~sheard/course/CS457-557/Notes/Laziness.pdf · 1 CS 457/557: Functional Languages Leveraging Laziness Mark](https://reader033.fdocuments.net/reader033/viewer/2022042404/5f19389d1438d900191d7cf6/html5/thumbnails/18.jpg)
Some Preliminaries:
separators :: [String]
separators = [ "=", "::" ]
pad :: Int -> String -> String
pad n s = take n (s ++ repeat ' ')
![Page 19: CS 457/557: Functional Languages - Computer Action Teamweb.cecs.pdx.edu/~sheard/course/CS457-557/Notes/Laziness.pdf · 1 CS 457/557: Functional Languages Leveraging Laziness Mark](https://reader033.fdocuments.net/reader033/viewer/2022042404/5f19389d1438d900191d7cf6/html5/thumbnails/19.jpg)
Patching Lines:
patchLine :: Int -> String -> (Int, String)
patchLine n cs = head (matches ++ [(0, cs)])
where
matches = [ let l = length s
in (l + length as,
pad (n-l) as ++ bs)
| (as, bs) <- zip (inits cs)
(tails cs),
s <- separators,
s `isPrefixOf` bs ]
Target length to end of first separator
Input string
Output string
Actual length to end of first separator
Default case Find first match
![Page 20: CS 457/557: Functional Languages - Computer Action Teamweb.cecs.pdx.edu/~sheard/course/CS457-557/Notes/Laziness.pdf · 1 CS 457/557: Functional Languages Leveraging Laziness Mark](https://reader033.fdocuments.net/reader033/viewer/2022042404/5f19389d1438d900191d7cf6/html5/thumbnails/20.jpg)
Tying the Knot (again):
main :: IO ()
main = getEnv "TM_SELECTED_TEXT"
>>= (putStr . align)
align :: String -> String
align s = unlines (map snd ps)
where w = foldr max 0 (map fst ps)
ps = map (patchLine w) (lines s)
![Page 21: CS 457/557: Functional Languages - Computer Action Teamweb.cecs.pdx.edu/~sheard/course/CS457-557/Notes/Laziness.pdf · 1 CS 457/557: Functional Languages Leveraging Laziness Mark](https://reader033.fdocuments.net/reader033/viewer/2022042404/5f19389d1438d900191d7cf6/html5/thumbnails/21.jpg)
An Editor Plugin:
![Page 22: CS 457/557: Functional Languages - Computer Action Teamweb.cecs.pdx.edu/~sheard/course/CS457-557/Notes/Laziness.pdf · 1 CS 457/557: Functional Languages Leveraging Laziness Mark](https://reader033.fdocuments.net/reader033/viewer/2022042404/5f19389d1438d900191d7cf6/html5/thumbnails/22.jpg)
Combining Techniques of Lazy
Programming
![Page 23: CS 457/557: Functional Languages - Computer Action Teamweb.cecs.pdx.edu/~sheard/course/CS457-557/Notes/Laziness.pdf · 1 CS 457/557: Functional Languages Leveraging Laziness Mark](https://reader033.fdocuments.net/reader033/viewer/2022042404/5f19389d1438d900191d7cf6/html5/thumbnails/23.jpg)
“Escape! That's the goal.
Rush Hour is a premier sliding block puzzle designed
to challenge your sequential-thinking skills (and perhaps your traffic-officer
aspirations as well).”
![Page 24: CS 457/557: Functional Languages - Computer Action Teamweb.cecs.pdx.edu/~sheard/course/CS457-557/Notes/Laziness.pdf · 1 CS 457/557: Functional Languages Leveraging Laziness Mark](https://reader033.fdocuments.net/reader033/viewer/2022042404/5f19389d1438d900191d7cf6/html5/thumbnails/24.jpg)
![Page 25: CS 457/557: Functional Languages - Computer Action Teamweb.cecs.pdx.edu/~sheard/course/CS457-557/Notes/Laziness.pdf · 1 CS 457/557: Functional Languages Leveraging Laziness Mark](https://reader033.fdocuments.net/reader033/viewer/2022042404/5f19389d1438d900191d7cf6/html5/thumbnails/25.jpg)
![Page 26: CS 457/557: Functional Languages - Computer Action Teamweb.cecs.pdx.edu/~sheard/course/CS457-557/Notes/Laziness.pdf · 1 CS 457/557: Functional Languages Leveraging Laziness Mark](https://reader033.fdocuments.net/reader033/viewer/2022042404/5f19389d1438d900191d7cf6/html5/thumbnails/26.jpg)
![Page 27: CS 457/557: Functional Languages - Computer Action Teamweb.cecs.pdx.edu/~sheard/course/CS457-557/Notes/Laziness.pdf · 1 CS 457/557: Functional Languages Leveraging Laziness Mark](https://reader033.fdocuments.net/reader033/viewer/2022042404/5f19389d1438d900191d7cf6/html5/thumbnails/27.jpg)
![Page 28: CS 457/557: Functional Languages - Computer Action Teamweb.cecs.pdx.edu/~sheard/course/CS457-557/Notes/Laziness.pdf · 1 CS 457/557: Functional Languages Leveraging Laziness Mark](https://reader033.fdocuments.net/reader033/viewer/2022042404/5f19389d1438d900191d7cf6/html5/thumbnails/28.jpg)
![Page 29: CS 457/557: Functional Languages - Computer Action Teamweb.cecs.pdx.edu/~sheard/course/CS457-557/Notes/Laziness.pdf · 1 CS 457/557: Functional Languages Leveraging Laziness Mark](https://reader033.fdocuments.net/reader033/viewer/2022042404/5f19389d1438d900191d7cf6/html5/thumbnails/29.jpg)
![Page 30: CS 457/557: Functional Languages - Computer Action Teamweb.cecs.pdx.edu/~sheard/course/CS457-557/Notes/Laziness.pdf · 1 CS 457/557: Functional Languages Leveraging Laziness Mark](https://reader033.fdocuments.net/reader033/viewer/2022042404/5f19389d1438d900191d7cf6/html5/thumbnails/30.jpg)
![Page 31: CS 457/557: Functional Languages - Computer Action Teamweb.cecs.pdx.edu/~sheard/course/CS457-557/Notes/Laziness.pdf · 1 CS 457/557: Functional Languages Leveraging Laziness Mark](https://reader033.fdocuments.net/reader033/viewer/2022042404/5f19389d1438d900191d7cf6/html5/thumbnails/31.jpg)
![Page 32: CS 457/557: Functional Languages - Computer Action Teamweb.cecs.pdx.edu/~sheard/course/CS457-557/Notes/Laziness.pdf · 1 CS 457/557: Functional Languages Leveraging Laziness Mark](https://reader033.fdocuments.net/reader033/viewer/2022042404/5f19389d1438d900191d7cf6/html5/thumbnails/32.jpg)
![Page 33: CS 457/557: Functional Languages - Computer Action Teamweb.cecs.pdx.edu/~sheard/course/CS457-557/Notes/Laziness.pdf · 1 CS 457/557: Functional Languages Leveraging Laziness Mark](https://reader033.fdocuments.net/reader033/viewer/2022042404/5f19389d1438d900191d7cf6/html5/thumbnails/33.jpg)
A Rush Hour Solver:
Uses lazy evaluation in three important ways:
–! Written in compositional style
–! Natural use of an infinite data structure (a search tree that is subsequently pruned to a finite tree
that eliminates duplicate puzzle positions)
–! Cyclic programming techniques used to implement breadth-first pruning of the search tree.
![Page 34: CS 457/557: Functional Languages - Computer Action Teamweb.cecs.pdx.edu/~sheard/course/CS457-557/Notes/Laziness.pdf · 1 CS 457/557: Functional Languages Leveraging Laziness Mark](https://reader033.fdocuments.net/reader033/viewer/2022042404/5f19389d1438d900191d7cf6/html5/thumbnails/34.jpg)
Representing the Board:
type Position = (Coord, Coord)
type Coord = Int
maxw, maxh :: Coord
maxw = 6
maxh = 6
![Page 35: CS 457/557: Functional Languages - Computer Action Teamweb.cecs.pdx.edu/~sheard/course/CS457-557/Notes/Laziness.pdf · 1 CS 457/557: Functional Languages Leveraging Laziness Mark](https://reader033.fdocuments.net/reader033/viewer/2022042404/5f19389d1438d900191d7cf6/html5/thumbnails/35.jpg)
Representing the Pieces:
type Vehicle = (Color, Type)
data Color = Red | … | Emerald
deriving (Eq, Show)
data Type = Car | Truck
deriving (Eq, Show)
len :: Type -> Int
len Car = 2
len Truck = 3
![Page 36: CS 457/557: Functional Languages - Computer Action Teamweb.cecs.pdx.edu/~sheard/course/CS457-557/Notes/Laziness.pdf · 1 CS 457/557: Functional Languages Leveraging Laziness Mark](https://reader033.fdocuments.net/reader033/viewer/2022042404/5f19389d1438d900191d7cf6/html5/thumbnails/36.jpg)
Representing Puzzles:
type Puzzle = [Piece]
type Piece = (Vehicle, Position, Orientation)
data Orientation = W | H
vehicle :: Piece -> Vehicle
vehicle (v, p, o) = v
solved :: Piece -> Bool
solved p = p == ((Red, Car), (4,3), W)
![Page 37: CS 457/557: Functional Languages - Computer Action Teamweb.cecs.pdx.edu/~sheard/course/CS457-557/Notes/Laziness.pdf · 1 CS 457/557: Functional Languages Leveraging Laziness Mark](https://reader033.fdocuments.net/reader033/viewer/2022042404/5f19389d1438d900191d7cf6/html5/thumbnails/37.jpg)
puzzle1 :: Puzzle
puzzle1 =
[ ((LtGreen, Car), (0,5), W),
((Yellow, Truck), (5,3), H),
((Violet, Truck), (0,2), H),
((Blue, Truck), (3,2), H),
((Red, Car), (1,3), W),
((Orange, Car), (0,0), H),
((LtBlue, Car), (4,1), W),
((Emerald, Truck), (2,0), W) ]
![Page 38: CS 457/557: Functional Languages - Computer Action Teamweb.cecs.pdx.edu/~sheard/course/CS457-557/Notes/Laziness.pdf · 1 CS 457/557: Functional Languages Leveraging Laziness Mark](https://reader033.fdocuments.net/reader033/viewer/2022042404/5f19389d1438d900191d7cf6/html5/thumbnails/38.jpg)
From Moves to Trees: …
…
…
…
…
…
![Page 39: CS 457/557: Functional Languages - Computer Action Teamweb.cecs.pdx.edu/~sheard/course/CS457-557/Notes/Laziness.pdf · 1 CS 457/557: Functional Languages Leveraging Laziness Mark](https://reader033.fdocuments.net/reader033/viewer/2022042404/5f19389d1438d900191d7cf6/html5/thumbnails/39.jpg)
Checking for Obstructions:
puzzleObstructs :: Puzzle -> Position -> Bool
puzzleObstructs puzzle pos
= or [ pieceObstructs p pos | p<-puzzle ]
pieceObstructs :: Piece -> Position -> Bool
pieceObstructs ((c,t), (x,y), W) (u,v)
= (y==v) && (x<=u) && (u<x+len t)
pieceObstructs ((c,t), (x,y), H) (u,v)
= (x==u) && (y<=v) && (v<y+len t)
![Page 40: CS 457/557: Functional Languages - Computer Action Teamweb.cecs.pdx.edu/~sheard/course/CS457-557/Notes/Laziness.pdf · 1 CS 457/557: Functional Languages Leveraging Laziness Mark](https://reader033.fdocuments.net/reader033/viewer/2022042404/5f19389d1438d900191d7cf6/html5/thumbnails/40.jpg)
Calculating Moves:
moves :: Puzzle -> Piece -> [Piece]
moves puzzle piece = step back piece ++ step forw piece
where
back :: Piece -> Maybe Piece
back (v, (x,y), W)
| x>0 && free p = Just (v, p, W)
where p = (x-1, y)
...
free = not . puzzleObstructs puzzle
step :: (a -> Maybe a) -> a -> [a]
step dir p = case dir p of
Nothing -> []
Just p’ -> p' : step dir p'
![Page 41: CS 457/557: Functional Languages - Computer Action Teamweb.cecs.pdx.edu/~sheard/course/CS457-557/Notes/Laziness.pdf · 1 CS 457/557: Functional Languages Leveraging Laziness Mark](https://reader033.fdocuments.net/reader033/viewer/2022042404/5f19389d1438d900191d7cf6/html5/thumbnails/41.jpg)
Forests and Trees:
type Forest a = [Tree a]
data Tree a = Node a [Tree a]
mapTree :: (a -> b) -> Tree a -> Tree b
mapTree f (Node x cs)
= Node (f x) (map (mapTree f) cs)
pathsTree :: Tree a -> Tree [a]
pathsTree = descend []
where descend xs (Node x cs)
= Node xs' (map (descend xs') cs)
where xs' = x:xs
![Page 42: CS 457/557: Functional Languages - Computer Action Teamweb.cecs.pdx.edu/~sheard/course/CS457-557/Notes/Laziness.pdf · 1 CS 457/557: Functional Languages Leveraging Laziness Mark](https://reader033.fdocuments.net/reader033/viewer/2022042404/5f19389d1438d900191d7cf6/html5/thumbnails/42.jpg)
Making Trees:
forest :: Puzzle -> Forest (Piece, Puzzle)
forest ps = [ Node (m, qs) (forest qs)
| (as, p, bs) <- splits ps,
m <- moves (as++bs) p,
let qs = as ++ [m] ++ bs ]
splits :: [a] -> [([a], a, [a])]
splits xs = … exercise to the reader …
(e.g., splits "dog"
= [("",'d',"og"),("d",'o',"g"),("do",'g',"")])
![Page 43: CS 457/557: Functional Languages - Computer Action Teamweb.cecs.pdx.edu/~sheard/course/CS457-557/Notes/Laziness.pdf · 1 CS 457/557: Functional Languages Leveraging Laziness Mark](https://reader033.fdocuments.net/reader033/viewer/2022042404/5f19389d1438d900191d7cf6/html5/thumbnails/43.jpg)
Pruning the Tree:
•! We want to avoid puzzle solutions in which the same piece is moved in two successive turns
•! The generated tree may contain many instances of this pattern
•! We can prune away repetition using: trimRel :: (a -> a -> Bool) -> Tree a -> Tree a
trimRel rel (Node x cs)
= Node x (filter (\(Node y _) -> rel x y) cs)
![Page 44: CS 457/557: Functional Languages - Computer Action Teamweb.cecs.pdx.edu/~sheard/course/CS457-557/Notes/Laziness.pdf · 1 CS 457/557: Functional Languages Leveraging Laziness Mark](https://reader033.fdocuments.net/reader033/viewer/2022042404/5f19389d1438d900191d7cf6/html5/thumbnails/44.jpg)
Eliminating Duplicate Puzzles:
•! We don’t want to explore any single puzzle configuration more than once
•! We want to find shortest possible solutions (requires breadth-first search of the forest)
xs1
xs2
xs3
xs4
xs1
xs2
xs3
[]
xsi = distinct positions that have been found by the end of the ith level
![Page 45: CS 457/557: Functional Languages - Computer Action Teamweb.cecs.pdx.edu/~sheard/course/CS457-557/Notes/Laziness.pdf · 1 CS 457/557: Functional Languages Leveraging Laziness Mark](https://reader033.fdocuments.net/reader033/viewer/2022042404/5f19389d1438d900191d7cf6/html5/thumbnails/45.jpg)
trimDups :: Eq b => (a -> b) -> Forest a -> Forest a
trimDups val f = f'
where
(f', xss)= prune f ([]:xss)
prune [] xss = ([], xss)
prune (Node v cs : ts) xss
= let x = val v in
if x `elem` head xss
then prune ts xss
else let (cs', xss1) = prune cs (tail xss)
(ts', xss2)
= prune ts ((x:head xss):xss1)
in (Node v cs' : ts', xss2)
knot tying
infinite list
![Page 46: CS 457/557: Functional Languages - Computer Action Teamweb.cecs.pdx.edu/~sheard/course/CS457-557/Notes/Laziness.pdf · 1 CS 457/557: Functional Languages Leveraging Laziness Mark](https://reader033.fdocuments.net/reader033/viewer/2022042404/5f19389d1438d900191d7cf6/html5/thumbnails/46.jpg)
Breadth-First Search:
bfs :: Tree t -> [t]
bfs = concat . bft
bft (Node x cs) = [x] : bff cs
bff = foldr (combine (++)) [] . map bft
combine :: (a -> a -> a) -> [a] -> [a] -> [a]
combine f (x:xs) (y:ys) = f x y : combine f xs ys
combine f [] ys = ys
combine f xs [] = xs
![Page 47: CS 457/557: Functional Languages - Computer Action Teamweb.cecs.pdx.edu/~sheard/course/CS457-557/Notes/Laziness.pdf · 1 CS 457/557: Functional Languages Leveraging Laziness Mark](https://reader033.fdocuments.net/reader033/viewer/2022042404/5f19389d1438d900191d7cf6/html5/thumbnails/47.jpg)
The Main Solver:
solve :: Puzzle -> IO ()
solve = putStrLn
. unlines
. map show
. reverse
. head
. filter (solved . head)
. concat
. bff
. map (pathsTree . mapTree fst)
. trimDups (\(p,ps) -> ps)
. map (trimRel (\(v,ps) (w,qs) -> vehicle v /= vehicle w))
. forest
Written in a fully compositional style
![Page 48: CS 457/557: Functional Languages - Computer Action Teamweb.cecs.pdx.edu/~sheard/course/CS457-557/Notes/Laziness.pdf · 1 CS 457/557: Functional Languages Leveraging Laziness Mark](https://reader033.fdocuments.net/reader033/viewer/2022042404/5f19389d1438d900191d7cf6/html5/thumbnails/48.jpg)
Summary:
•! Laziness provides new ways (with respect to other paradigms) for us to think about and express algorithms
•! Enhanced modularity from compositional style, infinite data structures, etc…
•! Novel programming techniques like knot tying/circular programs …
•! Further Reading:
–! Why Functional Programming Matters, John Hughes
–! The Semantic Elegance of Applicative Languages, D. A. Turner
–! Using Circular Programs to Eliminate Multiple Traversals of Data Structures, Richard Bird