現時点ではWorkLog
、開始日と終了日を持つタイプがあります。開始日と終了日から派生する期間レンズも追加したいと思います。読み取り専用にするか、値が変更された場合は終了日を変更する必要があります (1 つしか使用しませんが、両方のバージョンを実装する方法を知りたいです)。
これが私のコードです。workLogDurationRO
基本的に、メインパスですべてのテストを取得する関数と関数を実装できればworkLogDurationRW
、私の質問に答えることができます。
{-# LANGUAGE TemplateHaskell #-}
module Main where
import Control.Lens
-- Keep times simple for this example
newtype TimeStamp = TimeStamp Int deriving (Show, Eq)
newtype TimeDifference = TimeDifference Int deriving (Show, Eq)
(-.-) :: TimeStamp -> TimeStamp -> TimeDifference
(TimeStamp a) -.- (TimeStamp b) = TimeDifference (a - b)
data WorkLog = WorkLog {
_workLogDescription :: String
, _workLogStartTime :: TimeStamp
, _workLogEndTime :: TimeStamp
}
makeLenses ''WorkLog
-- | Just return the difference between the start and end time
workLogDurationRO :: Getter WorkLog TimeDifference
workLogDurationRO = error "TODO write me!"
-- | Like the read only version, but when used with a setter,
-- change the end date.
workLogDurationRW :: Lens' WorkLog TimeDifference
workLogDurationRW = error "TODO write me!"
ensure :: String -> Bool -> IO ()
ensure _ True = putStrLn "Test Passed"
ensure msg False = putStrLn $ "Test Failed: " ++ msg
main :: IO ()
main = do
let testWorkLog = WorkLog "Work 1" (TimeStamp 40) (TimeStamp 100)
ensure "read only lens gets correct duration" $
testWorkLog^.workLogDurationRO == TimeDifference 60
ensure "read+write lens gets correct duration" $
testWorkLog^.workLogDurationRW == TimeDifference 60
let newWorkLog = testWorkLog & workLogDurationRW .~ TimeDifference 5
ensure "writeable lens changes end time" $
newWorkLog^.workLogEndTime == TimeStamp 45