ch1 progress
This commit is contained in:
parent
8fad24c02c
commit
26cfef70c8
1 changed files with 162 additions and 0 deletions
162
ch01.lhs
162
ch01.lhs
|
@ -1,6 +1,9 @@
|
||||||
Chapter 1: Functional Programming
|
Chapter 1: Functional Programming
|
||||||
===
|
===
|
||||||
|
|
||||||
|
> import Prelude hiding (foldl, foldr)
|
||||||
|
> import Control.Exception
|
||||||
|
|
||||||
Exercise 1.2
|
Exercise 1.2
|
||||||
---
|
---
|
||||||
|
|
||||||
|
@ -36,3 +39,162 @@ number of times in the rest of this book. Give appropriate definitions.
|
||||||
>
|
>
|
||||||
> single [x] = True
|
> single [x] = True
|
||||||
> single _ = False
|
> single _ = False
|
||||||
|
|
||||||
|
Exercise 1.4
|
||||||
|
---
|
||||||
|
|
||||||
|
Write down a definition of reverse that takes linear time. One possibility is to use a foldl.
|
||||||
|
|
||||||
|
> -- This takes linear time because the list basically builds up backwards
|
||||||
|
> reverse :: [a] -> [a]
|
||||||
|
> reverse = foldl (\a x -> x : a) []
|
||||||
|
|
||||||
|
Exercise 1.5
|
||||||
|
---
|
||||||
|
|
||||||
|
Express both map and filter as an instance of foldr.
|
||||||
|
|
||||||
|
> map2 :: (a -> b) -> [a] -> [b]
|
||||||
|
> map2 f = foldr (\x a -> f x : a) []
|
||||||
|
>
|
||||||
|
> filter2 :: (a -> Bool) -> [a] -> [a]
|
||||||
|
> filter2 f = foldr (\x a -> if f x then x : a else a) []
|
||||||
|
|
||||||
|
Exercise 1.6
|
||||||
|
---
|
||||||
|
|
||||||
|
Express `foldr f e . filter p` as an instance of foldr.
|
||||||
|
|
||||||
|
> composed :: (a -> b -> b) -> (a -> Bool) -> b -> [a] -> b
|
||||||
|
> composed f p e = foldr f e . filter p
|
||||||
|
>
|
||||||
|
> composed2 :: (a -> b -> b) -> (a -> Bool) -> b -> [a] -> b
|
||||||
|
> composed2 f p = foldr (\x a -> if p x then f x a else a)
|
||||||
|
|
||||||
|
Exercise 1.7
|
||||||
|
---
|
||||||
|
|
||||||
|
The function takeWhile returns the longest initial segment of a list all of
|
||||||
|
whose elements satisfy a given test. Moreover, its running time is proportional
|
||||||
|
to the length of the result, not to the length of the input. Express takeWhile
|
||||||
|
as an instance of foldr, thereby demonstrating once again that a foldr need not
|
||||||
|
process the whole of its argument before terminating.
|
||||||
|
|
||||||
|
> -- I think the fact that foldr doesn't consume the whole thing here is only
|
||||||
|
> -- due to laziness, since foldr builds up the expression from the back.
|
||||||
|
> takeWhile :: (a -> Bool) -> [a] -> [a]
|
||||||
|
> takeWhile f = foldr (\x a -> if f x then x : a else []) []
|
||||||
|
|
||||||
|
Exercise 1.8
|
||||||
|
---
|
||||||
|
|
||||||
|
The Data.List library contains a function dropWhileEnd which drops the longest
|
||||||
|
suffix of a list all of whose elements satisfy a given boolean test. For
|
||||||
|
example,
|
||||||
|
|
||||||
|
> _ = dropWhileEnd even [1, 4, 3, 6, 2, 4] == [1, 4, 3]
|
||||||
|
|
||||||
|
Define dropWhileEnd as an instance of foldr.
|
||||||
|
|
||||||
|
> dropWhileEnd :: Eq a => (a -> Bool) -> [a] -> [a]
|
||||||
|
> dropWhileEnd f = foldr (\x a -> if f x && a == [] then [] else x : a) []
|
||||||
|
|
||||||
|
Exercise 1.9
|
||||||
|
---
|
||||||
|
|
||||||
|
An alternative definition of foldr is
|
||||||
|
|
||||||
|
> foldr f e xs = if null xs then e else f (head xs) (foldr f e (tail xs))
|
||||||
|
|
||||||
|
Dually, an alternative definition of foldl is
|
||||||
|
|
||||||
|
> foldl f e xs = if null xs then e else f (foldl f e (init xs)) (last xs)
|
||||||
|
|
||||||
|
where last and init are dual to head and tail. What is the problem with this
|
||||||
|
definition of foldl?
|
||||||
|
|
||||||
|
> -- init and last are both O(n) operations since they require traversing to
|
||||||
|
> -- the end as opposed to head and tail which are O(1) which means overall this
|
||||||
|
> -- alternate definition of foldl is really expensive.
|
||||||
|
|
||||||
|
Exercise 1.10
|
||||||
|
---
|
||||||
|
|
||||||
|
Bearing the examples
|
||||||
|
|
||||||
|
> -- foldr (⊕) e [x, y, z] == x ⊕ (y ⊕ (z ⊕ e))
|
||||||
|
> -- foldl (⊕) e [x, y, z] == ((e ⊕ x) ⊕ y) ⊕ z
|
||||||
|
|
||||||
|
in mind, under what simple conditions on (⊕) and e do we have
|
||||||
|
|
||||||
|
> -- foldr (⊕) e xs = foldl (⊕) e xs
|
||||||
|
|
||||||
|
for all finite lists xs?
|
||||||
|
|
||||||
|
> -- (⊕) just needs to be associative and e the identity.
|
||||||
|
>
|
||||||
|
> -- This will give us x ⊕ (y ⊕ (z)) for foldr and (x ⊕ y) ⊕ z for foldl, which
|
||||||
|
> -- still preserves the order of x, y, and z so if (⊕) is associative then
|
||||||
|
> -- the statements are equivalent.
|
||||||
|
|
||||||
|
Exercise 1.11
|
||||||
|
---
|
||||||
|
|
||||||
|
Given a list of digits representing a natural number, construct a function
|
||||||
|
integer which converts the digits into that number. For example,
|
||||||
|
|
||||||
|
> _ = integer [1, 4, 8, 4, 9, 3] == 148493
|
||||||
|
|
||||||
|
Next, given a list of digits representing a real number r in the range 0 <= r <
|
||||||
|
1, construct a function fraction which converts the digits into the
|
||||||
|
corresponding fraction. For example,
|
||||||
|
|
||||||
|
> _ = fraction [1, 4, 8, 4, 9, 3] == 0.148493
|
||||||
|
|
||||||
|
> integer :: [Int] -> Int
|
||||||
|
> integer = foldl (\a x -> 10 * a + x) 0
|
||||||
|
>
|
||||||
|
> fraction :: [Int] -> Double
|
||||||
|
> fraction = (/ 10) . foldr (\x a -> fromIntegral x + a / 10) 0
|
||||||
|
|
||||||
|
Exercise 1.12
|
||||||
|
---
|
||||||
|
|
||||||
|
Complete the right hand sides of:
|
||||||
|
|
||||||
|
> -- map (foldl f e) . inits = ???
|
||||||
|
> -- map (foldr f e) . tails = ???
|
||||||
|
|
||||||
|
> -- TODO
|
||||||
|
|
||||||
|
Exercise 1.13
|
||||||
|
---
|
||||||
|
|
||||||
|
Define the function
|
||||||
|
|
||||||
|
> apply :: Int -> (a -> a) -> a -> a
|
||||||
|
|
||||||
|
that applies a function a specified number of times to a value.
|
||||||
|
|
||||||
|
> apply 0 f x = x
|
||||||
|
> apply n f x = apply (n - 1) f (f x)
|
||||||
|
|
||||||
|
Exercise 1.14
|
||||||
|
---
|
||||||
|
|
||||||
|
Can the function inserts associated with the inductive definition of perms be
|
||||||
|
expressed as an instance of foldr?
|
||||||
|
|
||||||
|
> -- TODO
|
||||||
|
|
||||||
|
Exercise 1.15
|
||||||
|
---
|
||||||
|
|
||||||
|
Give a definition of remove for which
|
||||||
|
|
||||||
|
> -- perms3 [] = [[]]
|
||||||
|
> -- perms3 xs = [x : ys | x <- xs, y <- perms3 (remove x xs)]
|
||||||
|
|
||||||
|
computes the permutations of a list. Is the first clause necessary? What is the
|
||||||
|
type of perms3, and can one generate the permutations of a list of functions
|
||||||
|
with this definition?
|
||||||
|
|
Loading…
Reference in a new issue