My solution to the exercise on p. 352.
1.Rewrite getRandom to use do notation.
getRandom = do
gen <- get
let (val,gen') = random gen
put gen'
return val
My solution to the exercise on p. 352.
1.Rewrite getRandom to use do notation.
My answers to the exercises of chapter 8.
Page 205:
2. While filesystems on Unix are usually sensitive to case (e.g. “G” vs. “g”) in file names, Windows filesystems are not. Add a parameter to the globToRegex and matchesGlob functions that allows control over case sensitive matching.
Note that the solution below ignores ranges in character classes.
Page 212:
1. Glob patterns are simple enough to interpret that it's easy to write a matcher directly in Haskell, rather than going through the regexp machinery. Give it a try.
Note: I forgot to implement negated character classes.
My answers to the exercises of the fourth chapter.
Page 84:
1. Write your own “safe” definitions of the standard partial list functions, but make sure they never fail.
2. Write a function splitWith that acts similarly to words but takes a predicate and a list of any type, and then splits its input list on every element for which the predicate returns False.
Page 97:
1. Use a fold (choosing the appropriate fold will make your code much simpler) to rewrite and improve upon the asInt function from the section called “Explicit recursion” on page 85.
6. Write your own definition of concat using foldr.
My answers to the exercises of chapter 3.
Page 60:
1. Write the converse of fromList for the List type: a function that takes a List a and generates a [a].
2. Define a tree type that has only one constructor, like our Java example. Instead of the Empty constructor, use the Maybe type to refer to a node’s children.
Page 69:
1. Write a function that computes the number of elements in a list. To test it, ensure that it gives the same answers as the standard length function.
2. Add a type signature for your function to your source file. To test it, load the source file into ghci again.
3. Write a function that computes the mean of a list, i.e. the sum of all elements in the list divided by its length. (You may need to use the fromIntegral function to convert the length of the list from an integer into a floating point number.)
4. Turn a list into a palindrome, i.e. it should read the same both backwards and forwards. For example, given the list [1,2,3], your function should return [1,2,3,3,2,1].
5. Write a function that determines whether its input list is a palindrome.
6. Create a function that sorts a list of lists based on the length of each sublist. (You may want to look at the sortBy function from the Data.List module.)
Or, less bulky, using the on function from the Data.Function module.
7. Define a function that joins a list of lists together using a separator value.
8. Using the binary tree type that we defined earlier in this chapter, write a function that will determine the height of the tree. The height is the largest number of hops from the root to an Empty. For example, the tree Empty has height zero; Node "x" Empty Empty has height one; Node "x" Empty (Node "y" Empty Empty) has height two; and so on.
9. Consider three two-dimensional points a, b, and c. If we look at the angle formed by the line segment from a to b and the line segment from b to c, it either turns left, turns right, or forms a straight line. Define a Direction data type that lets you represent these possibilities.
My answers to the exercises of the second chapter.
Page 25:
1. What are the types of the following expressions?
False :: Bool (["foo", "bar"], 'a') :: ([String], Char) [(True, []), (False, [['a']])] :: [(Bool,[[Char]])]
Page 39:
1. Haskell provides a standard function, last :: [a] -> a, that returns the last element of a list. From reading the type alone, what are the possible valid behaviors (omitting crashes and infinite loops) that this function could have?
From the type alone there is no way to find out what the real type is, neither is there a way to manipulate a value of that type, thus the “only” thing the code can do is return an element of the list.
What are a few things that this function clearly cannot do?
2. Write a function, lastButOne, that returns the element before the last.
lastButOne = head . tail . reverse
Load your lastButOne function into ghci and try it out on lists of different lengths. What happens when you pass it a list that’s too short?
Prelude> lastButOne "a" *** Exception: Prelude.head: empty list
Here are my answers to the exercises of chapter 1.
1. Enter the following expressions into ghci What are their types?
Prelude> 5 + 8 5 + 8 13 it :: Integer Prelude> 3 * 5 + 8 3 * 5 + 8 23 it :: Integer Prelude> 2 + 4 2 + 4 6 it :: Integer Prelude> (+) 2 4 (+) 2 4 6 it :: Integer Prelude> sqrt 16 sqrt 16 4.0 it :: Double Prelude> succ 6 succ 6 7 it :: Integer Prelude> succ 7 succ 7 8 it :: Integer Prelude> pred 9 pred 9 8 it :: Integer Prelude> pred 8 pred 8 7 it :: Integer Prelude> sin (pi / 2) sin (pi / 2) 1.0 it :: Double Prelude> truncate pi truncate pi 3 it :: Integer Prelude> round 3.5 round 3.5 4 it :: Integer Prelude> round 3.4 round 3.4 3 it :: Integer Prelude> floor 3.7 floor 3.7 3 it :: Integer Prelude> ceiling 3.3 ceiling 3.3 4 it :: Integer
2. From ghci, type :? to print some help. Define a variable and then type :show bindings. What do you see?
Prelude> let x = 1 let x = 1 Prelude> :show bindings :show bindings it :: Integer = 4 x :: Integer = _ Prelude> x x 1 Prelude> :show bindings :show bindings it :: Integer = 4 x :: Integer = 1
3. The words function counts the number of words in a string. Modify the WC.hs example in order to count the number of words in a file.
main = interact wordCount where wordCount input = show (length (words input)) ++ "n"
4. Modify the WC.hs example again, in order to print the number of characters in a file.
main = interact wordCount where wordCount input = show (length input) ++ "n"