지금은 WorkLog
유형으로 시작일과 종료일이 있습니다. 또한 기간 렌즈를 추가하여 시작일과 종료일에서 파생됩니다. 읽기 전용이거나 값이 변경되면 종료 날짜를 변경해야합니다 (두 버전을 구현하는 방법을 알고 싶습니다. 단 하나만 사용 하겠지만).렌즈 라이브러리를 사용하여 다른 렌즈에 의존하는 복잡한 렌즈를 어떻게 작성합니까?
여기 내 코드입니다. 기본적으로, 당신은 과 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
는
덕분에, (이 가늠자에 분명하다하더라도) 렌즈 기능을 사용하여 생각하지 않았다을 . 아직도이 도서관 주위에 내 머리를지고 :) –