У меня есть слишком сложная функция, чтобы я мог четко указать, какой должен быть тип функции.Я пытаюсь заставить GHC согласиться с тем, что я ожидаю, это то, что он ожидает.Во-первых, функция, что я думаю, что она должна делать.Затем, когда возникает путаница.
flagScheduled ((Left (MkUFD day)):rest) = do
match <- runDB $ selectList [TestStartDate ==. Just day,
TestStatus /<-. [Passed,Failed]] []
case (L.null match) of
True -> do
processedDays <- ([(Left $ MkUFD day)] :) <$> flagScheduled rest
return processedDays
False -> do
let flaggedRange = (calcFlagged match)
product = (testFirmware . snd . P.head) match
processedDays <- (flagScheduled'
([(Left $ MkUFD day)] ++
(L.take flaggedRange) rest) (show product) :) <$>
(flagScheduled . L.drop flaggedRange) rest
return processedDays
flagScheduled ((Right day):rest) = do
processedDays <- ((Right $ day):) <$> flagScheduled rest
return processedDays
flagScheduled _ = return []
calcFlagged (( _ ,(Test _ _ (Just startDate) (Just endDate) _ _ )) : rest) =
fromIntegral $ C.diffDays endDate startDate
flagScheduled' toBeFlagged product =
L.map (flagIt product) toBeFlagged
where flagIt product (Left (MkUFD day)) = Right $
MkCal $
Right $
MkUAD $
Left $
MkSDay day
(read product :: Product)
Reserved
Идея состоит в том, что я начинаю с [Either UnFlaggedDay CalendarDay]
, я перебираю список, превращая некоторые из UnFlaggedDay
s в CalendarDay
s.Другие функции преобразуют остальные UnFlaggedDay
с.Ниже я определяю типы, с которыми я работаю.
newtype AvailableDay = MkAD (Text, C.Day)
deriving (Show, Eq)
newtype UnAvailableDay = MkUAD (Either ScheduledDay Out_Of_Office)
deriving Show
data ScheduledDay = MkSDay C.Day Product ScheduledState
deriving Show
newtype ReservedDay = MkRDay (C.Day,Product)
deriving (Ord,Show,Eq,Read)
newtype ASAPDay = MkADay (C.Day,Product)
deriving (Ord,Show,Eq,Read)
newtype UnFlaggedDay = MkUFD C.Day
newtype CalendarDay = MkCal (Either AvailableDay UnAvailableDay)
deriving Show
Итак, вот проблема, когда я компилирую, я получаю эту ошибку, которая сама по себе не сбивает с толку.
Utils/BuildDateList.hs:173:44:
Couldn't match expected type `Either a0 b0'
with actual type `[Either UnFlaggedDay CalendarDay]'
Expected type: GGHandler sub0 master0 monad0 [Either a0 b0]
Actual type: GGHandler
sub0 master0 monad0 [[Either UnFlaggedDay CalendarDay]]
In the return type of a call of `flagScheduled'
In the second argument of `(<$>)', namely `flagScheduled rest'
Хорошохорошо, похоже, все, что мне нужно сделать, это применить правильно размещенный конкат, и я могу заставить фактический тип GGHandler
sub0 master0 monad0 [[Either UnFlaggedDay CalendarDay]]
соответствовать ожидаемому типу GGHandler
sub0 master0 monad0 [[Either UnFlaggedDay CalendarDay]]
Но подождите, не все так просто.Вот одна из многих попыток, и, независимо от того, где я размещаю конкат, кажется, что это приводит к одной и той же ошибке.
Utils/BuildDateList.hs:164:16:
Couldn't match expected type `[Either UnFlaggedDay b0]'
with actual type `Either UnFlaggedDay b0'
Expected type: GGHandler
sub0 master0 monad0 [[Either UnFlaggedDay b0]]
Actual type: GGHandler
sub0 master0 monad0 [Either UnFlaggedDay b0]
In the expression: return $ P.concat processedDays
In the expression:
do { processedDays <- ([(Left $ MkUFD day)] :)
<$>
flagScheduled rest;
return $ P.concat processedDays }
Вы видели, что там произошло?Вот изменения, которые я сделал.Я передал processedDays
в concat
перед тем, как передать в return
.
flagScheduled ((Left (MkUFD day)):rest) = do
match <- runDB $ selectList [TestStartDate ==. Just day,
TestStatus /<-. [Passed,Failed]] []
case (L.null match) of
True -> do
processedDays <- ([(Left $ MkUFD day)] :) <$> flagScheduled rest
return $ P.concat processedDays
False -> do
let flaggedRange = (calcFlagged match)
product = (testFirmware . snd . P.head) match
processedDays <- (flagScheduled'
([(Left $ MkUFD day)] ++
(L.take flaggedRange) rest) (show product) :) <$>
(flagScheduled . L.drop flaggedRange) rest
return $ P.concat processedDays
flagScheduled ((Right day):rest) = do
processedDays <- ((Right $ day):) <$> flagScheduled rest
return $ P.concat processedDays
flagScheduled _ = return []
Так что тот факт, что то, что выглядит как прямое изменение, которое не является, указывает мне, что я неЯ действительно не понимаю, в чем проблема.Есть идеи?
Обновление: я внес изменения, предложенные Даниэлем, но получил эту ошибку:
Utils/BuildDateList.hs:169:37:
Couldn't match expected type `[Either UnFlaggedDay t0]'
with actual type `Either UnFlaggedDay b0'
In the first argument of `(++)', namely `(Left $ MkUFD day)'
In the first argument of `flagScheduled'', namely
`((Left $ MkUFD day) ++ (P.take flaggedRange) rest)'
In the first argument of `(:)', namely
`flagScheduled'
((Left $ MkUFD day) ++ (P.take flaggedRange) rest) (show product)'
Обновление: эта проблема была решена только для выявления других (похожих) проблем.Я собираюсь воспользоваться советом, данным здесь, чтобы двигаться вперед с этим.