Redline's Autodidact Repo

changeset 49:5b8bc8cbfa98

Updated previous RWH solutions and posted all but the last 3 solutions from Chapter 3.
author Brit Butler <redline6561@gmail.com>
date Mon Mar 16 13:03:29 2009 -0400 (10 months ago)
parents 9fa9c4c5639c
children 245c03689e82
files books/rwh/chapter01/WC.hs books/rwh/chapter01/exercise03.hs books/rwh/chapter01/exercise04.hs books/rwh/chapter02/add.hs books/rwh/chapter02/exercise02.hs books/rwh/chapter02/exercise03.hs books/rwh/chapter02/myDrop.hs books/rwh/chapter03/AlgebraicVector.hs books/rwh/chapter03/BadIndent.hs books/rwh/chapter03/BadPattern.hs books/rwh/chapter03/BadTree.hs books/rwh/chapter03/BogusPattern.hs books/rwh/chapter03/BookStore.hs books/rwh/chapter03/Braces.hs books/rwh/chapter03/GlobalVariable.hs books/rwh/chapter03/GoodIndent.hs books/rwh/chapter03/Guards.hs books/rwh/chapter03/Indentation.hs books/rwh/chapter03/Lending.hs books/rwh/chapter03/ListADT.hs books/rwh/chapter03/LocalFunction.hs books/rwh/chapter03/MySecond.hs books/rwh/chapter03/NestedLets.hs books/rwh/chapter03/Nullable.hs books/rwh/chapter03/Roygbiv.hs books/rwh/chapter03/ShapeUnion.hs books/rwh/chapter03/Tuple.hs books/rwh/chapter03/add.hs books/rwh/chapter03/exercise01.hs books/rwh/chapter03/exercise02.hs books/rwh/chapter03/exercise03_04.hs books/rwh/chapter03/exercise05.hs books/rwh/chapter03/exercise06.hs books/rwh/chapter03/exercise07.hs books/rwh/chapter03/exercise08.hs books/rwh/chapter03/exercise09.hs books/rwh/chapter03/exercise10.hs books/rwh/chapter03/exercise11.hs books/rwh/chapter03/exercise12.hs books/rwh/chapter03/letwhere.hs books/rwh/functions.hs
line diff
     1.1 --- a/books/rwh/chapter01/WC.hs	Mon Mar 09 14:49:35 2009 -0400
     1.2 +++ b/books/rwh/chapter01/WC.hs	Mon Mar 16 13:03:29 2009 -0400
     1.3 @@ -2,4 +2,4 @@
     1.4  -- lines beginning with "--" are comments
     1.5  
     1.6  main = interact wordCount
     1.7 -     where wordCount input = show (length (lines input)) ++ "\n"
     1.8 \ No newline at end of file
     1.9 +       where wordCount input = show (length (lines input)) ++ "\n"
     2.1 --- a/books/rwh/chapter01/exercise03.hs	Mon Mar 09 14:49:35 2009 -0400
     2.2 +++ b/books/rwh/chapter01/exercise03.hs	Mon Mar 16 13:03:29 2009 -0400
     2.3 @@ -1,4 +1,4 @@
     2.4  -- file: chapter01/exercise03.hs
     2.5  
     2.6  main = interact wordCount
     2.7 -     where wordCount input = show (length (words input)) ++ "\n"
     2.8 \ No newline at end of file
     2.9 +       where wordCount input = show (length (words input)) ++ "\n"
     3.1 --- a/books/rwh/chapter01/exercise04.hs	Mon Mar 09 14:49:35 2009 -0400
     3.2 +++ b/books/rwh/chapter01/exercise04.hs	Mon Mar 16 13:03:29 2009 -0400
     3.3 @@ -1,4 +1,4 @@
     3.4  -- file: chapter01/exercise04.hs
     3.5  
     3.6  main = interact wordCount
     3.7 -     where wordCount input = show (length input) ++ "\n"
     3.8 \ No newline at end of file
     3.9 +       where wordCount input = show (length input) ++ "\n"
     4.1 --- a/books/rwh/chapter02/add.hs	Mon Mar 09 14:49:35 2009 -0400
     4.2 +++ b/books/rwh/chapter02/add.hs	Mon Mar 16 13:03:29 2009 -0400
     4.3 @@ -1,4 +1,3 @@
     4.4  -- file: chapter02/add.hs
     4.5 --- authors mistakenly titled as ch03/add.hs
     4.6  
     4.7  add a b = a + b
     4.8 \ No newline at end of file
     5.1 --- a/books/rwh/chapter02/exercise02.hs	Mon Mar 09 14:49:35 2009 -0400
     5.2 +++ b/books/rwh/chapter02/exercise02.hs	Mon Mar 16 13:03:29 2009 -0400
     5.3 @@ -1,5 +1,5 @@
     5.4  -- file: chapter02/exercise02.hs
     5.5 --- section: The Type of a Function of More Than One Argument (1)
     5.6 +-- section: The Type of a Function of More Than One Argument
     5.7  
     5.8  -- The last function could return the first or last elements of a list or a random element.
     5.9  -- It cannot return a list and it cannot take more than one argument.
    5.10 \ No newline at end of file
     6.1 --- a/books/rwh/chapter02/exercise03.hs	Mon Mar 09 14:49:35 2009 -0400
     6.2 +++ b/books/rwh/chapter02/exercise03.hs	Mon Mar 16 13:03:29 2009 -0400
     6.3 @@ -1,8 +1,6 @@
     6.4  -- file: chapter02/exercise03.hs
     6.5  -- section: The Type of a Function of More Than One Argument
     6.6  
     6.7 -lastButOne xs = if (length xs == 2)
     6.8 -           then head xs
     6.9 ---           else if (length xs < 2)
    6.10 ---                then print "Your list is too short. It must have 2 or more elements."
    6.11 -           else lastButOne (drop 1 xs)
    6.12 \ No newline at end of file
    6.13 +lastButOne xs = if length xs == 2
    6.14 +                then head xs
    6.15 +                else lastButOne (tail xs) -- or (drop 1 xs)
     7.1 --- a/books/rwh/chapter02/myDrop.hs	Mon Mar 09 14:49:35 2009 -0400
     7.2 +++ b/books/rwh/chapter02/myDrop.hs	Mon Mar 16 13:03:29 2009 -0400
     7.3 @@ -3,5 +3,21 @@
     7.4  
     7.5  myDrop :: Int -> [a] -> [a]
     7.6  myDrop n xs = if n <= 0 || null xs
     7.7 -       then xs
     7.8 -       else myDrop (n - 1) (tail xs)
     7.9 \ No newline at end of file
    7.10 +              then xs
    7.11 +              else myDrop (n - 1) (tail xs)
    7.12 +
    7.13 +myDrop2 :: Int -> [a] -> [a]
    7.14 +myDrop2 n xs -- I think I like this best.
    7.15 +        | n <= 0    = xs
    7.16 +        | null xs   = xs
    7.17 +        | otherwise = myDrop2 (n - 1) (tail xs)
    7.18 +
    7.19 +myDrop3 :: Int -> [a] -> [a]
    7.20 +myDrop3 n xs
    7.21 +        | n <= 0 || null xs = xs
    7.22 +        | otherwise         = myDrop3 (n - 1) (tail xs)
    7.23 +
    7.24 +niceDrop :: Int -> [a] -> [a]
    7.25 +niceDrop n xs | n <= 0 = xs
    7.26 +niceDrop _ []          = []
    7.27 +niceDrop n (_:xs)      = niceDrop (n - 1) xs
    7.28 \ No newline at end of file
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/books/rwh/chapter03/AlgebraicVector.hs	Mon Mar 16 13:03:29 2009 -0400
     8.3 @@ -0,0 +1,12 @@
     8.4 +-- file: chapter03/AlgebraicVector.hs
     8.5 +-- x and y coordinates or lengths.
     8.6 +data Cartesian2D = Cartesian2D Double Double
     8.7 +                   deriving (Eq, Show)
     8.8 +
     8.9 +-- Angle and distance (magnitude).
    8.10 +data Polar2D = Polar2D Double Double
    8.11 +               deriving (Eq, Show)
    8.12 +
    8.13 +-- Polar Coordinates and Cartesian Coordinates are different.
    8.14 +-- The lesson? Use tuples in small, local situations.
    8.15 +-- Otherwise stick to Type or Data declarations.
    8.16 \ No newline at end of file
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/books/rwh/chapter03/BadIndent.hs	Mon Mar 16 13:03:29 2009 -0400
     9.3 @@ -0,0 +1,8 @@
     9.4 +-- file: chapter03/BadIndent.hs
     9.5 +-- This is the leftmost column.
     9.6 +
     9.7 +   -- Our first declaration is in column 4.
     9.8 +   firstBadIndentation = 1
     9.9 +
    9.10 +  -- Our second is left of the first, which is illegal!
    9.11 +  secondBadIndentation = 2
    9.12 \ No newline at end of file
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/books/rwh/chapter03/BadPattern.hs	Mon Mar 16 13:03:29 2009 -0400
    10.3 @@ -0,0 +1,6 @@
    10.4 +-- file: chapter03/BadPattern.hs
    10.5 +
    10.6 +badExample (x:xs) = x + badExample xs
    10.7 +
    10.8 +goodExample (x:xs) = x + goodExample xs
    10.9 +goodExample _ = 0 -- Wildcards are nice sometimes.
   10.10 \ No newline at end of file
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/books/rwh/chapter03/BadTree.hs	Mon Mar 16 13:03:29 2009 -0400
    11.3 @@ -0,0 +1,8 @@
    11.4 +-- file: chapter03/BadTree.hs
    11.5 +
    11.6 +bad_nodesAreSame (Node a _ _) (Node a _ _) = Just a
    11.7 +bad_nodesAreSame _            _            = Nothing
    11.8 +
    11.9 +nodesAreSame (Node a _ _) (Node b _ _)
   11.10 +             | a == b  = Just a
   11.11 +nodesAreSame _ _ = Nothing
   11.12 \ No newline at end of file
    12.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.2 +++ b/books/rwh/chapter03/BogusPattern.hs	Mon Mar 16 13:03:29 2009 -0400
    12.3 @@ -0,0 +1,25 @@
    12.4 +-- file: ch03/BogusPattern.hs
    12.5 +
    12.6 +data Fruit = Apple | Orange
    12.7 +             deriving (Show)
    12.8 +
    12.9 +apple = "apple"
   12.10 +
   12.11 +orange = "orange"        
   12.12 +
   12.13 +-- This next section of code is jacked up.
   12.14 +
   12.15 +whichFruit :: String -> Fruit
   12.16 +whichFruit f = case f of
   12.17 +                 apple  -> Apple
   12.18 +                 orange -> Orange
   12.19 +
   12.20 +equational apple = Apple
   12.21 +equational orange = Orange
   12.22 +
   12.23 +-- We refer to a pattern that always succeeds as irrefutable.
   12.24 +-- Plain variable names and the wild card _ are examples of irrefutable patterns.
   12.25 +
   12.26 +betterFruit f = case f of
   12.27 +                  "apple"  -> Apple
   12.28 +                  "orange" -> Orange
   12.29 \ No newline at end of file
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/books/rwh/chapter03/BookStore.hs	Mon Mar 16 13:03:29 2009 -0400
    13.3 @@ -0,0 +1,84 @@
    13.4 +-- file: chapter03/BookStore.hs
    13.5 +
    13.6 +type CustomerID = Int
    13.7 +type ReviewBody = String
    13.8 +type BookRecord = (BookInfo, BookReview)
    13.9 +
   13.10 +type CardHolder = String
   13.11 +type CardNumber = String
   13.12 +type Address = [String]
   13.13 +
   13.14 +type BookID = Int -- Having all these type synonyms seems like boilerplate.
   13.15 +type BookTitle = String -- What can I do about it?
   13.16 +type BookAuthors = [String]
   13.17 +
   13.18 +data BookInfo = Book Int String [String]
   13.19 +                deriving (Show)
   13.20 +
   13.21 +data MagazineInfo = Magazine Int String [String]
   13.22 +                    deriving (Show)
   13.23 +
   13.24 +data BookReview = BookReview BookInfo CustomerID String
   13.25 +
   13.26 +data BetterReview = BetterReview BookInfo CustomerID ReviewBody
   13.27 +
   13.28 +data BillingInfo = CreditCard CardNumber CardHolder Address -- This is an example of an Algebraic Data Type...
   13.29 +                 | CashOnDelivery -- ...not to be confused with an Abstract Data Type...
   13.30 +                 | Invoice CustomerID -- ...it has several type constructor options within it.
   13.31 +                   deriving (Show) -- All data declarations are in fact Algebraic Data Types.
   13.32 +
   13.33 +bookID (Book id title authors) = id -- Pattern matching will magically pull out the values we stored earlier.
   13.34 +bookTitle (Book id title authors) = title -- Yay, pattern matching! Note that Haskell type fields are...
   13.35 +bookAuthors (Book id title authors) = authors -- ...positional. We refer to them by location, not name.
   13.36 +
   13.37 +nicerID (Book id _ _) = id -- These are equivalent pattern matching accessors to those above.
   13.38 +nicerTitle (Book _ title _) = title -- The _ character serves as a wildcard in the matching process.
   13.39 +nicerAuthors (Book _ _ authors) = authors -- A little bit more concise but still repetitive.
   13.40 +
   13.41 +-- IMPORTANT! When writing a series of patterns, match one against each type constructor. Or else.
   13.42 +
   13.43 +data Customer = Customer { -- Since those earlier accessors were boilerplate, we can use this nice...
   13.44 +      customerID      :: CustomerID -- ..."record syntax" to handle the problem and automatically...
   13.45 +    , customerName    :: String -- ...accessor functions. Ya know, "for free".
   13.46 +    , customerAddress :: Address
   13.47 +} deriving (Show)
   13.48 +
   13.49 +customer1 = Customer 271828 "J.R. Hacker"
   13.50 +            ["255 Syntax Ct",
   13.51 +             "Milpitas, CA 95134",
   13.52 +             "USA"]
   13.53 +
   13.54 +customer2 = Customer { -- Record syntax can also be used in construction, if you think it's clearer.
   13.55 +              customerID = 271829 -- Customers shouldn't share IDs. See customer1.
   13.56 +            , customerAddress = ["1048576 Disk Drive",
   13.57 +                                 "Milpitas, CA 95134",
   13.58 +                                 "USA"]
   13.59 +            , customerName = "Jane Q. Citizen"
   13.60 +            }
   13.61 +
   13.62 +book0 = Book 9780135072455 "Algebra of Programming"
   13.63 +         ["Richard Bird", "Oege de Moor"]
   13.64 +book1 = Book 0 "The Book of Imaginary Beings"
   13.65 +        ["Jorge Luis Borges"]
   13.66 +book2 = Book 1 "Cosmicomics"
   13.67 +        ["Italo Calvino"]
   13.68 +book3 = Book 173 "Use of Weapons"
   13.69 +        ["Iain M. Banks"]
   13.70 +book4 = Book 2 "The Wealth of Networks"
   13.71 +        ["Yochai Benkler"]
   13.72 +book5 = Book 6561 "Real World Haskell"
   13.73 +        ["John Goerzen", "Bryan O'Sullivan", "Don Stewart"]
   13.74 +book6 = Book 3 "Probability Theory"
   13.75 +        ["E.T.H. Jaynes"]
   13.76 +bookList = [book0,book1,book2,book3,book4,book5,book6]
   13.77 +
   13.78 +-- Identical Types :: ([Char],[Char])
   13.79 +a = ("Porpoise", "Grey")
   13.80 +b = ("Table", "Oak")
   13.81 +
   13.82 +-- Different Types
   13.83 +data Cetacean = Cetacean String String
   13.84 +data Furniture = Furniture String String
   13.85 +
   13.86 +c = Cetacean "Porpoise" "Grey"
   13.87 +d = Furniture "Table" "Oak"
   13.88 \ No newline at end of file
    14.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.2 +++ b/books/rwh/chapter03/Braces.hs	Mon Mar 16 13:03:29 2009 -0400
    14.3 @@ -0,0 +1,10 @@
    14.4 +-- file: chapter03/Braces.hs
    14.5 +
    14.6 +bar = let a = 1
    14.7 +          b = 2
    14.8 +          c = 3
    14.9 +      in a + b + c
   14.10 +
   14.11 +foo = let { a = 1;  b = 2;
   14.12 +        c = 3 }
   14.13 +      in a + b + c
   14.14 \ No newline at end of file
    15.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.2 +++ b/books/rwh/chapter03/GlobalVariable.hs	Mon Mar 16 13:03:29 2009 -0400
    15.3 @@ -0,0 +1,3 @@
    15.4 +-- file: chapter03/GlobalVariable.hs
    15.5 +
    15.6 +itemName = "Weighted Companion Cube"
    16.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.2 +++ b/books/rwh/chapter03/GoodIndent.hs	Mon Mar 16 13:03:29 2009 -0400
    16.3 @@ -0,0 +1,8 @@
    16.4 +-- file: chapter03/GoodIndent.hs
    16.5 +-- This is the leftmost column.
    16.6 +
    16.7 +   -- It's fine for top-level declarations to start in any column.
    16.8 +   firstGoodIndentation = 1
    16.9 +
   16.10 +   -- ...provided all subsequent declarations do, too!
   16.11 +   secondGoodIndentation = 2
   16.12 \ No newline at end of file
    17.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.2 +++ b/books/rwh/chapter03/Guards.hs	Mon Mar 16 13:03:29 2009 -0400
    17.3 @@ -0,0 +1,6 @@
    17.4 +-- file: chapter03/Guards.hs
    17.5 +
    17.6 +fromMaybe defval wrapper = 
    17.7 +    case wrapped of
    17.8 +      Nothing    -> defval
    17.9 +      Just value -> value
   17.10 \ No newline at end of file
    18.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    18.2 +++ b/books/rwh/chapter03/Indentation.hs	Mon Mar 16 13:03:29 2009 -0400
    18.3 @@ -0,0 +1,10 @@
    18.4 +-- file: chapter03/Indentation.hs
    18.5 +
    18.6 +foo = let firstDefinition = blah blah
    18.7 +          -- a comment-only line is treated as empty
    18.8 +                            continuation blah
    18.9 +
   18.10 +          -- we reduce the indentation, so this is a new definition
   18.11 +          secondDefinition = yada yada
   18.12 +                             continuation yada
   18.13 +      in whatever
   18.14 \ No newline at end of file
    19.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    19.2 +++ b/books/rwh/chapter03/Lending.hs	Mon Mar 16 13:03:29 2009 -0400
    19.3 @@ -0,0 +1,20 @@
    19.4 +-- file: chapter03/Lending.hs
    19.5 +
    19.6 +lend amount balance = let reserve    = 100
    19.7 +                          newBalance = balance - amount
    19.8 +                      in if balance < reserve
    19.9 +                         then Nothing
   19.10 +                         else Just newBalance
   19.11 +
   19.12 +lend2 amount balance = if amount < reserve * 0.5
   19.13 +                       then Just newBalance
   19.14 +                       else Nothing
   19.15 +    where reserve    = 100
   19.16 +          newBalance = balance - amount
   19.17 +
   19.18 +lend3 amount balance
   19.19 +      | amount <= 0            = Nothing
   19.20 +      | amount > reserve * 0.5 = Nothing
   19.21 +      | otherwise              = Just newBalance
   19.22 +     where reserve    = 100
   19.23 +           newBalance = balance - amount
   19.24 \ No newline at end of file
    20.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    20.2 +++ b/books/rwh/chapter03/ListADT.hs	Mon Mar 16 13:03:29 2009 -0400
    20.3 @@ -0,0 +1,27 @@
    20.4 +-- file: chapter03/ListADT.hs
    20.5 +
    20.6 +data List a = Cons a (List a)
    20.7 +            | Nil
    20.8 +              deriving (Show)
    20.9 +
   20.10 +data Tree a = Node a (Tree a) (Tree a)
   20.11 +            | Empty
   20.12 +              deriving (Show)
   20.13 +
   20.14 +-- Here are two simple recursive data types.
   20.15 +-- Lists and binary trees. For example...
   20.16 +-- a Tree is either a node with two children...
   20.17 +-- or an empty value.
   20.18 +
   20.19 +-- Want to see a neat proof of type equivalence...
   20.20 +-- between [a] and List a? Of course you do.
   20.21 +
   20.22 +fromList (x:xs) = Cons x (fromList xs)
   20.23 +         []     = Nil
   20.24 +
   20.25 +-- List a and [a] are an example of isomorphic types, types with the same shape.
   20.26 +
   20.27 +simpleTree = Node "parent" (Node "left child" Empty Empty)
   20.28 +                           (Node "right child" Empty Empty)
   20.29 +
   20.30 +-- Java's null value doesn't exist in Haskell so we use the Empty constructor instead.
   20.31 \ No newline at end of file
    21.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    21.2 +++ b/books/rwh/chapter03/LocalFunction.hs	Mon Mar 16 13:03:29 2009 -0400
    21.3 @@ -0,0 +1,7 @@
    21.4 +-- file: chapter03/LocalFunction.hs
    21.5 +
    21.6 +pluralise :: String -> [Int] -> [String]
    21.7 +pluralise word counts = map plural counts
    21.8 +       where plural 0 = "no " ++ word ++ "s"
    21.9 +             plural 1 = "one " ++ word ++ "s"
   21.10 +             plural n = show n ++ " " ++ word "s"
   21.11 \ No newline at end of file
    22.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    22.2 +++ b/books/rwh/chapter03/MySecond.hs	Mon Mar 16 13:03:29 2009 -0400
    22.3 @@ -0,0 +1,17 @@
    22.4 +-- file: chapter03/MySecond.hs
    22.5 +
    22.6 +mySecond :: [a] -> a
    22.7 +mySecond xs = if null (tail xs) -- Error reporting is nice to have but...
    22.8 +              then error "list too short" -- it doesn't let us choose whether to...
    22.9 +              else head (tail xs) -- crash or try to recover.
   22.10 +
   22.11 +safeSecond :: [a] -> Maybe a
   22.12 +safeSecond [] = Nothing
   22.13 +safeSecond xs - if null (tail xs) -- Maybe gives us that opportunity.
   22.14 +                then Nothing -- Nothing happens if null (tail xs).
   22.15 +                else Just (head (tail xs)) -- And if else then Just (head (tail xs)).
   22.16 +
   22.17 +-- This cleans up safeSecond with pattern matching. It's certainly more concise.
   22.18 +tidySecond :: [a] -> Maybe a
   22.19 +tidySecond (_:x:_) = Just x
   22.20 +tidySecond _       = Nothing
    23.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    23.2 +++ b/books/rwh/chapter03/NestedLets.hs	Mon Mar 16 13:03:29 2009 -0400
    23.3 @@ -0,0 +1,11 @@
    23.4 +-- file: chapter03/NestedLets.hs
    23.5 +
    23.6 +foo = let a = 1
    23.7 +      in let b = 2
    23.8 +         in a + b
    23.9 +
   23.10 +bar = let x = 1
   23.11 +      in ((let x = "foo" in x), x)
   23.12 +
   23.13 +quux a = let a = "foo"
   23.14 +         in a ++ "eek"
    24.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    24.2 +++ b/books/rwh/chapter03/Nullable.hs	Mon Mar 16 13:03:29 2009 -0400
    24.3 @@ -0,0 +1,15 @@
    24.4 +-- file: chapter03/Nullable.hs
    24.5 +
    24.6 +data Maybe a = Just a
    24.7 +             | Nothing
    24.8 +
    24.9 +someBool = Just True
   24.10 +
   24.11 +someString = Just "something"
   24.12 +
   24.13 +wrapped = Just (Just "wrapped")
   24.14 +
   24.15 +-- The Maybe type exists to allow things to fail.
   24.16 +-- There's a decent wikibook article on it here:
   24.17 +-- http://en.wikibooks.org/wiki/Haskell/Hierarchical_libraries/Maybe
   24.18 +-- I hope the book will cover Maybe, Just and Nothing in further detail later.
   24.19 \ No newline at end of file
    25.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    25.2 +++ b/books/rwh/chapter03/Roygbiv.hs	Mon Mar 16 13:03:29 2009 -0400
    25.3 @@ -0,0 +1,34 @@
    25.4 +-- file: chapter03/Roygbiv.hs
    25.5 +-- This is an example of "enumeration types" familiar as C's Enums in Haskell.
    25.6 +
    25.7 +-- NOTE: Haskell enumeration types cannot be used like Integers as in C enums.
    25.8 +-- Don't be against this. The Type system is saving you from yourself.
    25.9 +
   25.10 +data Roygbiv = Red
   25.11 +             | Orange
   25.12 +             | Yellow
   25.13 +             | Green
   25.14 +             | Blue
   25.15 +             | Indigo
   25.16 +             | Violet
   25.17 +               deriving (Eq, Show)
   25.18 +
   25.19 +-- Which is equivalent to
   25.20 +-- enum roygbiv {
   25.21 +--      red,
   25.22 +--      orange,
   25.23 +--      yellow,
   25.24 +--      green,
   25.25 +--      blue,
   25.26 +--      indigo,
   25.27 +--      violet
   25.28 +-- };
   25.29 +-- such as
   25.30 +data BookInfo = Book Int String [String]
   25.31 +                deriving (Show)
   25.32 +-- is equivalent to
   25.33 +-- struct book_info {
   25.34 +--        int id;
   25.35 +--        char *name;
   25.36 +--        char **authors;
   25.37 +--        };
   25.38 \ No newline at end of file
    26.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    26.2 +++ b/books/rwh/chapter03/ShapeUnion.hs	Mon Mar 16 13:03:29 2009 -0400
    26.3 @@ -0,0 +1,32 @@
    26.4 +-- file: chapter03/ShapeUnion.hs
    26.5 +
    26.6 +type Vector = (Double, Double)
    26.7 +
    26.8 +data Shape = Circle Vector Double
    26.9 +           | Poly [Vector]
   26.10 +
   26.11 +-- Is much nicer than...
   26.12 +
   26.13 +-- enum shape_type {
   26.14 +--      shape_circle,
   26.15 +--      shape_poly,
   26.16 +-- };
   26.17 +
   26.18 +-- struct circle {
   26.19 +--        struct vector centre;
   26.20 +--        float radius;
   26.21 +-- };
   26.22 +
   26.23 +-- struct poly {
   26.24 +--        size_t num_vertices;
   26.25 +--        struct vector *vertices;
   26.26 +-- };
   26.27 +
   26.28 +-- struct shape {
   26.29 +--        enum shape_type type;
   26.30 +--        union {
   26.31 +--        struct circle circle;
   26.32 +--        struct poly poly;
   26.33 +--        } shape;
   26.34 +-- 
   26.35 +-- };
   26.36 \ No newline at end of file
    27.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    27.2 +++ b/books/rwh/chapter03/Tuple.hs	Mon Mar 16 13:03:29 2009 -0400
    27.3 @@ -0,0 +1,7 @@
    27.4 +-- file: chapter03/Tuple.hs
    27.5 +
    27.6 +third (a,b,c) = c
    27.7 +
    27.8 +complicated (True, a, x:xs, 5) = (a, xs)
    27.9 +-- I feel like "complicated (True, a, [b], 5) = (a, (tail [b]))" should be equivalent but it throws an exception.
   27.10 +-- Something about Non-exhaustive patterns in function. Hrm. The pattern match must not have recognized the list.
   27.11 \ No newline at end of file
    28.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    28.2 +++ b/books/rwh/chapter03/add.hs	Mon Mar 16 13:03:29 2009 -0400
    28.3 @@ -0,0 +1,12 @@
    28.4 +-- file: chapter03/add.hs
    28.5 +
    28.6 +add a b = a + b
    28.7 +
    28.8 +myNot True = False
    28.9 +myNot False = True
   28.10 +
   28.11 +sumList (x:xs) = x + sumList xs
   28.12 +sumList [] = 0
   28.13 +
   28.14 +-- List notation is in fact short for a cons string. I.e. [1..5] is short for [1,2,3,4,5]
   28.15 +-- which is short for (1:(2:(3:(4:(5:[]))))).
    29.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    29.2 +++ b/books/rwh/chapter03/exercise01.hs	Mon Mar 16 13:03:29 2009 -0400
    29.3 @@ -0,0 +1,9 @@
    29.4 +-- file: chapter03/exercise01.hs
    29.5 +-- section: Recursive Types
    29.6 +
    29.7 +data List a = Cons a (List a)
    29.8 +            | Nil
    29.9 +              deriving (Show)
   29.10 +
   29.11 +toList (Cons a as) = a:(toList as)
   29.12 +toList Nil              = []
   29.13 \ No newline at end of file
    30.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    30.2 +++ b/books/rwh/chapter03/exercise02.hs	Mon Mar 16 13:03:29 2009 -0400
    30.3 @@ -0,0 +1,10 @@
    30.4 +-- file: chapter03/exercise02.hs
    30.5 +-- section: Recursive Types
    30.6 +
    30.7 +data Tree a = Node a (Maybe (Tree a)) (Maybe (Tree a))
    30.8 +              deriving (Show)
    30.9 +
   30.10 +-- Actually, what you want to handle Empty correctly is:
   30.11 +
   30.12 +data MyTree a = MyTree (Maybe (a, MyTree a, MyTree a))
   30.13 +                deriving (Show)
   30.14 \ No newline at end of file
    31.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    31.2 +++ b/books/rwh/chapter03/exercise03_04.hs	Mon Mar 16 13:03:29 2009 -0400
    31.3 @@ -0,0 +1,16 @@
    31.4 +-- file: chapter03/exercise03_04.hs
    31.5 +-- section: Conditional Evaluation with Guards
    31.6 +
    31.7 +myLength :: [a] -> Int
    31.8 +myLength xs = if null xs -- They're all pretty.
    31.9 +              then 0
   31.10 +              else 1 + myLength (tail xs)
   31.11 +
   31.12 +myLength2 :: [a] -> Int
   31.13 +myLength2 xs -- But I think this reads best, at least for non-haskellers.
   31.14 +          | null xs   = 0
   31.15 +          | otherwise = 1 + myLength (tail xs)
   31.16 +
   31.17 +myLength3 :: [a] -> Int
   31.18 +myLength3 []     = 0 -- And this is most concise and best for haskellers.
   31.19 +myLength3 (_:xs) = 1 + myLength3 xs
   31.20 \ No newline at end of file
    32.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    32.2 +++ b/books/rwh/chapter03/exercise05.hs	Mon Mar 16 13:03:29 2009 -0400
    32.3 @@ -0,0 +1,6 @@
    32.4 +-- file: chapter03/exercise05.hs
    32.5 +-- section: Conditional Evaluation with Guards
    32.6 +
    32.7 +listMean :: [Double] -> Double
    32.8 +listMean [] = 0
    32.9 +listMean xs = sum xs / fromIntegral (length xs)
   32.10 \ No newline at end of file
    33.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    33.2 +++ b/books/rwh/chapter03/exercise06.hs	Mon Mar 16 13:03:29 2009 -0400
    33.3 @@ -0,0 +1,9 @@
    33.4 +-- file: chapter03/exercise06.hs
    33.5 +-- section: Conditional Evaluation with Guards
    33.6 +
    33.7 +palindrome :: [a] -> [a]
    33.8 +palindrome [] = []
    33.9 +palindrome xs = xs ++ myReverse xs
   33.10 +
   33.11 +myReverse []     = []
   33.12 +myReverse (x:xs) = myReverse xs ++ [x]
   33.13 \ No newline at end of file
    34.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    34.2 +++ b/books/rwh/chapter03/exercise07.hs	Mon Mar 16 13:03:29 2009 -0400
    34.3 @@ -0,0 +1,10 @@
    34.4 +-- file: chapter03/exercise07.hs
    34.5 +-- section: Conditional Evaluation with Guards
    34.6 +
    34.7 +myReverse :: [a] -> [a]
    34.8 +myReverse []     = []
    34.9 +myReverse (x:xs) = myReverse xs ++ [x]
   34.10 +
   34.11 +-- isPalindrome :: [a] -> Bool
   34.12 +isPalindrome [] = True
   34.13 +isPalindrome xs = myReverse xs == xs
   34.14 \ No newline at end of file
    35.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    35.2 +++ b/books/rwh/chapter03/exercise08.hs	Mon Mar 16 13:03:29 2009 -0400
    35.3 @@ -0,0 +1,15 @@
    35.4 +-- file: chapter03/exercise08.hs
    35.5 +-- section: Conditional Evaluation with Guards
    35.6 +
    35.7 +import Data.List -- I've seen this before but it hasn't yet been introduced in the book. For shame.
    35.8 +
    35.9 +listSort :: [[a]] -> [[a]]
   35.10 +listSort [] = []
   35.11 +listSort x = sortBy f x
   35.12 +         where
   35.13 +                f p q = compare (length p) (length q) -- why does this last line work?!??
   35.14 +--              and how the hell would I do it with pattern patching?
   35.15 +
   35.16 +--listByLen :: [[a]] -> [[a]]
   35.17 +--listByLen []      = []
   35.18 +--listByLen (x:y:z) = sortBy (compare (length x) (length y)) z
   35.19 \ No newline at end of file
    36.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    36.2 +++ b/books/rwh/chapter03/exercise09.hs	Mon Mar 16 13:03:29 2009 -0400
    36.3 @@ -0,0 +1,17 @@
    36.4 +-- file: chapter03/exercise09.hs
    36.5 +-- section: Conditional Evaluation with Guards
    36.6 +
    36.7 +intersperse :: a -> [[a]] -> [a]
    36.8 +intersperse a xs
    36.9 +            | null xs        = []
   36.10 +            | length xs == 1 = head xs
   36.11 +            | otherwise      = head xs ++ [a] ++ intersperse a (tail xs)
   36.12 +
   36.13 +-- I definitely prefer the second version.
   36.14 +-- The solution was obvious but I forgot to write the concatenated a as [a]
   36.15 +-- which confused the type checker. ++ can only accept lists, of course.
   36.16 +
   36.17 +intersperse2 :: a -> [[a]] -> [a]
   36.18 +intersperse2 _ []     = []
   36.19 +intersperse2 _ (x:[]) = x
   36.20 +intersperse2 s (x:xs) = x ++ [s] ++ intersperse s xs
    37.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    37.2 +++ b/books/rwh/chapter03/exercise10.hs	Mon Mar 16 13:03:29 2009 -0400
    37.3 @@ -0,0 +1,36 @@
    37.4 +-- file: chapter03/exercise10.hs
    37.5 +-- section: Conditional Evaluation with Guards
    37.6 +
    37.7 +data Tree a = Node a (Tree a) (Tree a)
    37.8 +            | Empty
    37.9 +              deriving (Show)
   37.10 +
   37.11 +simpleTree = Node "parent" (Node "left child" Empty Empty)
   37.12 +                           (Node "right child" Empty Empty)
   37.13 +
   37.14 +-- Obviously, you never want to write code like complicatedTree.
   37.15 +-- This is for illustrative purposes only.
   37.16 +complicatedTree = Node "/" (Node "/boot" Empty
   37.17 +                                         (Node "/boot/grub" Empty Empty))
   37.18 +                           (Node "/home"
   37.19 +                                         (Node "/home/redline"
   37.20 +                                                                (Node "/home/redline/code"
   37.21 +                                                                (Node "/home/redline/code/books" Empty Empty)
   37.22 +                                                                (Node "/home/redline/code/random" Empty Empty))
   37.23 +                                                                (Node "/home/redline/videos" Empty Empty))
   37.24 +                                         (Node "/home/crazyman" Empty
   37.25 +                                                                (Node "/home/crazyman/music"
   37.26 +                                                                (Node "/home/crazyman/music/Singles" Empty Empty)
   37.27 +                                                                (Node "/home/crazyman/music/Albums"
   37.28 +                                                                (Node "/home/crazyman/music/Albums/Amon Tobin" Empty Empty) Empty))))
   37.29 +
   37.30 +-- This was mostly tricky because I needlessly tried to figure out the type Signature for treeHeight.
   37.31 +-- The pattern matching will figure out how to walk the tree. I don't really have to.
   37.32 +treeHeight Empty = 0
   37.33 +treeHeight (Node _ Empty Empty) = 1
   37.34 +treeHeight (Node _ subTL Empty) = 1 + treeHeight subTL
   37.35 +treeHeight (Node _ Empty subTR) = 1 + treeHeight subTR
   37.36 +treeHeight (Node _ subTL subTR)
   37.37 +           | treeHeight subTL == treeHeight subTR = 1 + treeHeight subTL
   37.38 +           | treeHeight subTL >  treeHeight subTR = 1 + treeHeight subTL
   37.39 +           | treeHeight subTL <  treeHeight subTR = 1 + treeHeight subTR
   37.40 \ No newline at end of file
    38.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    38.2 +++ b/books/rwh/chapter03/exercise11.hs	Mon Mar 16 13:03:29 2009 -0400
    38.3 @@ -0,0 +1,7 @@
    38.4 +-- file: chapter03/exercise11.hs
    38.5 +-- section: Conditional Evaluation with Guards
    38.6 +
    38.7 +data Direction = Left
    38.8 +               | Right
    38.9 +               | Straight
   38.10 +                 deriving (Show)
   38.11 \ No newline at end of file
    39.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    39.2 +++ b/books/rwh/chapter03/exercise12.hs	Mon Mar 16 13:03:29 2009 -0400
    39.3 @@ -0,0 +1,3 @@
    39.4 +-- file: chapter03/exercise12.hs
    39.5 +-- section: Conditional Evaluation with Guards
    39.6 +
    40.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    40.2 +++ b/books/rwh/chapter03/letwhere.hs	Mon Mar 16 13:03:29 2009 -0400
    40.3 @@ -0,0 +1,10 @@
    40.4 +-- file: chapter03/letwhere.hs
    40.5 +
    40.6 +bar = let b = 2
    40.7 +          c = True
    40.8 +      in let a = b
    40.9 +         in (a, c)
   40.10 +
   40.11 +foo = x
   40.12 +    where x = y
   40.13 +            where y = 2
   40.14 \ No newline at end of file
    41.1 --- a/books/rwh/functions.hs	Mon Mar 09 14:49:35 2009 -0400
    41.2 +++ b/books/rwh/functions.hs	Mon Mar 16 13:03:29 2009 -0400
    41.3 @@ -5,14 +5,19 @@
    41.4  
    41.5  -- GHCi functions: :set || :unset [prompt,], :?, :info (function), :type (expr), :load "filePath", :module + Data.Ratio, :show bindings.
    41.6  -- GHCi continued: many can be abbreviated with their first initial but not unset. it is the last well-typed expression.
    41.7 +-- GHC: -fwarn-incomplete-patterns will notify of patterns that don't match against all a type's constructors.
    41.8 +-- GHC: -fwarn-name-shadowing will notify of shadowed names in nested lets.
    41.9 +-- Type magic: data defines new type. type creates new type synonyms. deriving and show do what?
   41.10 +-- Types cont: What can I say about Maybe Nothing Just Empty?
   41.11  -- Arithmetic operators: + - / * ^ ** though negative numbers have to be written (-) number. Otherwise the expression is ill typed.
   41.12  -- Arithmetic continued: ^ does integer exponentiation while ** handles floating point. % is in Data.Ratio.
   41.13 --- Arithmetic continued: sqrt succ pred sin truncate round floor ceiling odd even compare mod
   41.14 +-- Arithmetic continued: sqrt succ pred sin truncate round floor ceiling odd even compare mod sum
   41.15  -- Note that prefix form is attained by enclosing the operator in parentheses followed by it's arguments.
   41.16  -- Hence (-) with one argument will subtract that argument from 0. It's polymorphic.
   41.17 --- Boolean Logic, Value Comparisons: && || == < > <= >= /= not
   41.18 --- Conditional: if then else
   41.19 --- Local assignment: let
   41.20 +-- Boolean Logic, Value Comparisons: && || == < > <= >= /= not otherwise
   41.21 +-- Conditional: if then else case | (|s are called guards and are used for conditional evaluation)
   41.22 +-- Local assignment: let starts variable declarations, in ends it and starts the function body. where is a let whose assignment
   41.23 +-- Local assignment: applies to the code behind it rather than in front of it.
   41.24  -- Lists: ++ (:) length head tail take drop null last
   41.25  -- Lists continued: The notation for list construction is brackets with comma separated values like so: [1,2,3] or ['a','b','c'].
   41.26  -- Lists continued: List enumeration can be done with eg. [1..20] to construct a list from one to 20 or [1,4..15] to specify stepping.
   41.27 @@ -20,5 +25,5 @@
   41.28  -- Lists continued: (:) is the constructor or cons function. It appends a single element to the front of the list i.e. (1 : [2,3]).
   41.29  -- Tuple operators: (on pairs: fst, snd)
   41.30  -- String handling: lines words
   41.31 --- IO: putStrLn print readFile
   41.32 +-- IO: putStrLn print readFile error
   41.33  -- Random functions: pi