У меня есть функция, слишком сложная для того, чтобы я мог указать, каким должен быть тип функции. Я пытаюсь заставить 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
в CalendarDay
. Другие функции преобразуют остальные UnFlaggedDay
s. Ниже я определяю типы, с которыми я работаю.
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'
Хорошо, хорошо, похоже, все, что мне нужно сделать, это применить удачный concat, и я могу сделать фактический тип GGHandler
sub0 master0 monad0 [[Either UnFlaggedDay CalendarDay]]
соответствующим ожидаемому типу GGHandler
sub0 master0 monad0 [[Either UnFlaggedDay CalendarDay]]
Но подождите, не все так просто. Вот одна попытка из многих, и независимо от того, где я размещаю concat, похоже, это приводит к одной и той же ошибке.
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)'
Обновление: эта проблема была решена, только чтобы выявить другие (похожие) проблемы. Я собираюсь воспользоваться советом, данным здесь, чтобы двигаться вперед с этим.