weekdaze-0.0.0.1: src-lib/WeekDaze/Aggregate/StudentClass.hs
{-
Copyright (C) 2013-2014 Dr. Alistair Ward
This file is part of WeekDaze.
WeekDaze is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
WeekDaze is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with WeekDaze. If not, see <http://www.gnu.org/licenses/>.
-}
{- |
[@AUTHOR@] Dr. Alistair Ward
[@DESCRIPTION@]
* This is a group of /student-bodies/, merged for the duration of a single booking in the timetable, or the bookings required for a single /course/.
* In contrast to a /student-body/, the members of a /student-class/ don't have identical 'Data.Student.Profile's,
but their requirements are sufficiently similar to permit them to study a /course/ together.
* Temporarily merging /student-bodies/, better utilises the available /teacher/s & /location/s,
by increasing the pool of /student/s available to be taught simultaneously.
-}
module WeekDaze.Aggregate.StudentClass(
-- * Types
-- ** Type-synonyms
StudentClass,
MnemonicSeparator,
-- * Constants
tag,
-- * Functions
merge,
getSize,
-- ** Translation
toHtml
) where
import Control.Arrow((***))
import qualified Data.Foldable
import qualified Data.List
import qualified Data.Set
import qualified Text.XHtml.Strict
import Text.XHtml.Strict((<<))
import qualified WeekDaze.Aggregate.StudentBody as Aggregate.StudentBody
import qualified WeekDaze.Size as Size
import qualified WeekDaze.Text.XHTML as Text.XHTML
-- | Used to qualify XML & CSS.
tag :: String
tag = "studentClass"
{- |
Whilst a /student-body/ represents a group with identical requirements,
when one or more /student-bodies/ have similar requirements for a single /subject/,
they can be temporarily merged to form a /class/.
-}
type StudentClass = Data.Set.Set Aggregate.StudentBody.StudentBody
-- | Used to separate /mnemonic/s, when merging a /student-class/ into a /student-body/.
type MnemonicSeparator = String
{- |
* Remove the boundaries separating the groups of /student/s within a class, to form a single /student-body/.
* The mnemonics for the constituent /student-bodies/ are concatenated to form a composite mnemonic for the new /student-body/.
* CAVEAT: any /student-Ids/ common to more than one /student-body/ within the /student-class/, will be merged.
* CAVEAT: a null set, will result in a null mnemonic, which will be rejected by 'Aggregate.StudentBody.mkStudentBody'.
-}
merge :: MnemonicSeparator -> StudentClass -> Aggregate.StudentBody.StudentBody
merge mnemonicSeparator = uncurry Aggregate.StudentBody.mkStudentBody . (
Data.List.intercalate mnemonicSeparator *** Data.Set.unions {-members-}
) . unzip . map Aggregate.StudentBody.toPair . Data.Set.toList
{- |
* Counts the number of /student/s in a class.
* CAVEAT: assumes that the /student-bodies/, from which the class is composed, are distinct.
-}
getSize :: Data.Foldable.Foldable foldable => foldable Aggregate.StudentBody.StudentBody -> Size.NStudents
getSize = Data.Foldable.foldr ((+) . Aggregate.StudentBody.getSize) 0
-- | Convert to XHTML.
toHtml :: StudentClass -> Text.XHtml.Strict.Html
toHtml = (Text.XHTML.mkXHTMLSpan tag <<) . Data.List.intersperse (Text.XHtml.Strict.stringToHtml ", ") . map Text.XHtml.Strict.toHtml . Data.Set.toList