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