diff --git a/README.md b/README.md index 3024c5f..909dfa3 100644 --- a/README.md +++ b/README.md @@ -586,14 +586,16 @@ newtype WallTime = WallTime (Int, Int) deriving (Show) -- this is our backend. It can add minutes to a WallTime representation addMinutesToWallTime :: Int -> WallTime -> WallTime -addMinutesToWallTime x (WallTime (h, m)) = +addMinutesToWallTime x (WallTime (h, m)) = let (hAdd, mAdd) = x `quotRem` 60 hNew = h + hAdd - mNew = m + mAdd - in if mNew >= 60 - then WallTime ((hNew + 1) `rem` 24, mNew-60) + mNew = m + mAdd + in if mNew >= 60 + then + let (dnew, hnew') = (hNew + 1) `quotRem` 24 + in WallTime (24*dnew + hnew', mNew-60) else WallTime (hNew, mNew) - + -- this is our time representation in Minutes that we want to use in the frontend newtype Minute = Minute Int deriving (Show) diff --git a/src/Adapter.hs b/src/Adapter.hs index 55a124a..db8311f 100644 --- a/src/Adapter.hs +++ b/src/Adapter.hs @@ -17,12 +17,14 @@ newtype WallTime = WallTime (Int, Int) deriving (Show) -- this is our backend. It can add minutes to a WallTime representation addMinutesToWallTime :: Int -> WallTime -> WallTime -addMinutesToWallTime x (WallTime (h, m)) = +addMinutesToWallTime x (WallTime (h, m)) = let (hAdd, mAdd) = x `quotRem` 60 hNew = h + hAdd - mNew = m + mAdd - in if mNew >= 60 - then WallTime ((hNew + 1) `rem` 24, mNew-60) + mNew = m + mAdd + in if mNew >= 60 + then + let (dnew, hnew') = (hNew + 1) `quotRem` 24 + in WallTime (24*dnew + hnew', mNew-60) else WallTime (hNew, mNew) -- this is our time representation in Minutes that we want to use in the frontend diff --git a/src/Main.hs b/src/Main.hs index 12e612f..586b1fc 100644 --- a/src/Main.hs +++ b/src/Main.hs @@ -7,6 +7,7 @@ import Composite import Visitor import Adapter import Builder +import TemplateMethod main :: IO () main = do @@ -18,4 +19,5 @@ main = do visitorDemo adapterDemo builderDemo + templateMethodDemo diff --git a/src/TemplateMethod.hs b/src/TemplateMethod.hs new file mode 100644 index 0000000..2ada30e --- /dev/null +++ b/src/TemplateMethod.hs @@ -0,0 +1,34 @@ +module TemplateMethod where + +import Adapter (unmarshalWM, marshalMW, addMinutesToWallTime, Minute (..), WallTime (..) ) + +addMinutesTemplate :: (Int -> WallTime -> WallTime) -> Int -> Minute -> Minute +addMinutesTemplate tf x = + unmarshalWM . + tf x . + marshalMW + +-- implements linear addition even for values > 1440 +linearTimeAdd :: Int -> Minute -> Minute +linearTimeAdd = addMinutesTemplate addMinutesToWallTime + +-- implements cyclic addition, respecting a 24 hour (1440 Min) cycle +cyclicTimeAdd :: Int -> Minute -> Minute +cyclicTimeAdd = addMinutesTemplate addMinutesToWallTime' + + +-- a 24 hour (1440 min) cyclic version of addition: 1400 + 100 = 60 +addMinutesToWallTime' :: Int -> WallTime -> WallTime +addMinutesToWallTime' x (WallTime (h, m)) = + let (hAdd, mAdd) = x `quotRem` 60 + hNew = h + hAdd + mNew = m + mAdd + in if mNew >= 60 + then WallTime ((hNew + 1) `rem` 24, mNew-60) + else WallTime (hNew, mNew) + +templateMethodDemo = do + putStrLn "TemplateMethod -> higher order function -> typeclass default implementations" + putStrLn $ "linear time: " ++ (show $ linearTimeAdd 100 (Minute 1400)) + putStrLn $ "cyclic time: " ++ (show $ cyclicTimeAdd 100 (Minute 1400)) + putStrLn ""