Last active
August 29, 2015 14:18
-
-
Save cschneid/f0cc220552a5bb8c193e to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Grocery.Calendar where | |
import Data.Time | |
import Grocery.Types.Meal | |
import Control.Lens | |
import Data.Ord | |
import Data.List (sortBy) | |
type Calendar = [(Day, [Meal])] | |
createMealCalendar :: [Meal] -> Calendar | |
createMealCalendar [] = [] | |
createMealCalendar meals = createMealCalendar' [] [firstDay..lastDay] sortedMeals | |
where | |
firstDay = (head meals) ^. day | |
lastDay = (last meals) ^. day | |
sortedMeals = sortBy (comparing (^. day)) meals | |
-- first case, empty calendar, create the first day & meal | |
createMealCalendar' [] dds@(d:ds) (m:ms) = createMealCalendar' [(d, [m])] dds ms | |
-- base case, when we run out of meals to add, we're done | |
createMealCalendar' cal _ [] = cal | |
-- base case, when we run out of days, something odd happened | |
createMealCalendar' _ [] _ = error "Ran out of days!?" | |
-- recursive case. init & last are safe due to previous check. | |
createMealCalendar' cal dds@(d:ds) mms@(m:ms) = -- if this meal belongs on this day, add it and recurse | |
if m ^. day == d | |
then let previousCal = init cal | |
previousMealList = (snd . last) cal | |
updatedDay = (d, previousMealList ++ [m]) | |
newCal = previousCal ++ [updatedDay] | |
in createMealCalendar' newCal dds ms | |
-- Advance one day when the meal doesn't belong | |
else let newCal = (cal ++ [(d, [])]) | |
in createMealCalendar' newCal ds mms |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment