假设今天是 2019 年 7 月 23 日(实际上是原始帖子的日期)。如果我们用Duckling处理“从一月到二月”这样的短语,Duckling 会将其链接到下一年:即从 2020 年 1 月到 2020 年 2 月。这是因为 2019 年 1 月到 2 月的时间段已经是在过去和以下方法中选择指定时间段之后的第一个间隔。
执行此操作的方法如下:
runTimeIntervalsPredicate
:: TimeIntervalType -> Predicate
-> Predicate -> SeriesPredicate
runTimeIntervalsPredicate intervalType pred1 pred2 = timeSeqMap True f pred1
where
-- Pick the first interval *after* the given time segment
f thisSegment ctx = case runPredicate pred2 thisSegment ctx of
(_, firstFuture:_) -> Just $
timeInterval intervalType thisSegment firstFuture
_ -> Nothing
尽管我篡改了 Duckling 代码以根据平台的需要对其进行调整,但我不是一个非常流利的 Haskeller,这让我不知所措。
所以这里的问题是:我如何阻止这种转向未来的日期范围?
附录:
runPredicate
也是一种方法,看起来像这样
runPredicate :: Predicate -> SeriesPredicate
runPredicate EmptyPredicate{} = \_ _ -> ([], [])
runPredicate (SeriesPredicate (NoShow p)) = p
runPredicate TimeDatePredicate{..}
-- This should not happen by construction, but if it does then
-- empty time series should be ok
| isNothing tdHour && isJust tdAMPM = \_ _ -> ([], [])
runPredicate TimeDatePredicate{..} =
foldr1 runCompose toCompose
where
-- runComposePredicate performs best when the first predicate is of
-- smaller grain, that's why we order by grain here
toCompose = catMaybes
[ runSecondPredicate <$> tdSecond
, runMinutePredicate <$> tdMinute
, uncurry (runHourPredicate tdAMPM) <$> tdHour
, runDayOfTheWeekPredicate <$> tdDayOfTheWeek
, runDayOfTheMonthPredicate <$> tdDayOfTheMonth
, runMonthPredicate <$> tdMonth
, runYearPredicate <$> tdYear
]
runPredicate (IntersectPredicate pred1 pred2) =
runIntersectPredicate pred1 pred2
runPredicate (TimeIntervalsPredicate ty pred1 pred2) =
runTimeIntervalsPredicate ty pred1 pred2
runPredicate (ReplaceIntersectPredicate pred1 pred2 pred3) =
runReplaceIntersectPredicate pred1 pred2 pred3
应该也贴出timeSeqMap
方法
-- | Applies `f` to each interval yielded by `g`.
-- | Intervals including "now" are in the future.
timeSeqMap
:: Bool
-- Given an interval and range, compute a single new interval
-> (TimeObject -> TimeContext -> Maybe TimeObject)
-- First-layer series generator
-> Predicate
-- Series generator for values that come from `f`
-> SeriesPredicate