Skip to content

Commit

Permalink
added some more to Chapter3
Browse files Browse the repository at this point in the history
  • Loading branch information
mzero committed Feb 12, 2011
1 parent fec4600 commit 93c8ae7
Show file tree
Hide file tree
Showing 5 changed files with 206 additions and 1 deletion.
2 changes: 1 addition & 1 deletion seed/Chapter3/Step_3_4.hs
Expand Up @@ -10,7 +10,7 @@ page = thehtml <<
]
]

-- Rewrite all of this to use a type synonym.
-- Rewrite all of this to use a type synonym for the tuple.

toDoItems :: [(Bool, String)] -- a list of tuples: each a Bool and String
toDoItems =
Expand Down
57 changes: 57 additions & 0 deletions seed/Chapter3/Step_3_5.hs
@@ -0,0 +1,57 @@
module Step_3_5 where

import Slides

page = slideDeck "Chapter 3"
[ codeSlide "Not that safe"
"Type synonyms are quick and easy and often the right choice, but \
\don't offer as much type saftey as possible. Consider:"
[ "type Range = (Int, Int)"
, "inRange :: Range -> Int -> Bool"
, "inRange (lo,hi) x = lo <= x && x <= hi"
, ""
, "type Point = (Int, Int)"
, "p :: Point"
, "p = (3,7)"
, ""
, "ick = inRange p 4 -- compiles!"
]
, codeSlide "Data Types"
"Data types let you create a type that is distinct. When you so you \
\define a constructor that builds values of the type:"
[ "data Range = Range Int Int"
, "inRange :: Range -> Int -> Bool"
, "inRange (Range lo hi) x = lo <= x && x <= hi"
, ""
, "data Point = Point Int Int"
, "p :: Point"
, "p = Point 3 7"
, ""
, "ick = inRange p 4 -- now this is a compile error"
]
, codeSlide "Multiple Constrcutors"
"Data types are very powerful. They can have more than one constructor \
\and each constructor can have any number of values:"
[ "data Direction = North | East | South | West"
, " deriving (Eq, Show)"
, ""
, "data Weather = Sunny | Rainy Double | Windy Double Direction"
, "describe :: Weather -> String"
, "describe Sunny = \"lovely\""
, "describe (Rainy inches) | inches < 0.2 = \"drizzle\""
, " | otherwise = \"wet\""
, "describe (Windy speed dir) = "
, " \"blowin' \" ++ show speed ++ \" from \" ++ show dir"
]
, codeSlide "Wait, Deriving What?"
"The deriving clause on the data declaration is a bit of boilerplate \
\saver that will make your data do more. Here are some of the things \
\you can 'derive' for your data automatically:"
[ "Eq -- works with == and /= operators"
, "Ord -- works with <, >, etc.."
, "Show -- works with show"
, "Read -- works with read"
, "Enum -- convertable to/from integers"
, "Bounded -- has a min and max value"
]
]
59 changes: 59 additions & 0 deletions seed/Chapter3/Step_3_6.hs
@@ -0,0 +1,59 @@
module Step_3_6 where

import Text.Html

page = thehtml <<
[ header << (thetitle << "Output")
, body <<
[ h1 << "A to do list:"
, thediv << toDoHtml
, h1 << "# people invited:"
, p << show (headcount invited)
]
]

-- We've written two lists.

data ToDo = ToDo String | Done String

toDoItems :: [ToDo]
toDoItems =
[ Done "Pick up avacados"
, Done "Make snacks"
, ToDo "Clean house"
, ToDo "Have party"
]


data Invite = Invite String Int

who :: Invite -> String
who (Invite name count) = name

invited :: [Invite]
invited =
[ Invite "Amy" 1
, Invite "Bob" 7 -- he's got lots of kids
, Invite "Cam" 2
, Invite "Doris" 3
, Invite "Edgar" 2
, Invite "Fran" 2
]

formatToDo :: ToDo -> Html
-- Try writing this

renderToDo :: [ToDo] -> [Html]
renderToDo ts = map formatToDo ts

toDoHtml :: Html
toDoHtml = ulist << renderToDo toDoItems

-- NEXT

-- Write this function

headcount :: [Invite] -> Int
headcount is = 0 -- this list was just a place holder, delete it


86 changes: 86 additions & 0 deletions seed/Chapter3/Step_3_7.hs
@@ -0,0 +1,86 @@
module Step_3_7 where

import Text.Html

page = thehtml <<
[ header << (thetitle << "Output")
, body <<
[ h1 << "A to do list:"
, thediv << toDoHtml
, reminderHtml
, h1 << "# people invited:"
, p << show (headcount invited)
]
]

data ToDo = ToDo String | Done String

toDoItems :: [ToDo]
toDoItems =
[ Done "Pick up avacados"
, Done "Make snacks"
, ToDo "Clean house"
, ToDo "Have party"
]

-- We need a function to return the next item to do.
-- Something like:
-- whatToDoNext :: [ToDo] -> ToDo

-- But what should it return if they are all done?
-- Enter Maybe:
whatToDoNext :: [ToDo] -> Maybe String

-- The return type is Maybe String -- in the same way [String] is a type 'built'
-- from the String type, Maybe String is a type 'built' from the String type. But
-- rather than a list, values of type Maybe String can have one of two forms:
-- Just someString
-- Nothing
whatToDoNext (Done item : ts) = whatToDoNext ts
whatToDoNext (ToDo item : ts) = Just item
whatToDoNext [] = Nothing

formatNotice :: Maybe String -> Html
formatNotice Nothing = noHtml
formatNotice (Just item) = h1 << ("*** DO THIS: " ++ item ++ " ***")

reminderHtml :: Html
reminderHtml = formatNotice $ whatToDoNext toDoItems


formatToDo :: ToDo -> Html
formatToDo (ToDo item) = li << bold << item
formatToDo (Done item) = li << item

renderToDo :: [ToDo] -> [Html]
renderToDo ts = map formatToDo ts

toDoHtml :: Html
toDoHtml = ulist << renderToDo toDoItems

-- Try changing the toDoItems to be all Done and see how this works


-- NEXT
-- Add an optional partner or spouse to the invite data type.
-- Add a list of invitiees (and optional partners!) to the page.

data Invite = Invite String Int

who :: Invite -> String
who (Invite name count) = name

invited :: [Invite]
invited =
[ Invite "Amy" 1
, Invite "Bob" 7 -- he's got lots of kids
, Invite "Cam" 2
, Invite "Doris" 3
, Invite "Edgar" 2
, Invite "Fran" 2
]

headcount :: [Invite] -> Int
headcount [] = 0
headcount (Invite who count : is) = count + headcount is

3 changes: 3 additions & 0 deletions seed/lib/Tutorial.hs
Expand Up @@ -69,6 +69,9 @@ steps =
, Step 3 2 Code
, Step 3 3 Slides
, Step 3 4 Code
, Step 3 5 Slides
, Step 3 6 Code
, Step 3 7 Code
]

stepUrls :: [String]
Expand Down

0 comments on commit 93c8ae7

Please sign in to comment.