我有一个函数太复杂了,我无法明确函数类型应该是什么。我正在努力让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
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'
好的,看起来我需要做的就是应用一个位置很好的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 []
事实上,看起来像是一个没有直接变化的事实,向我表明我并不真正理解问题是什么。有什么想法吗?
更新:我做了Daniel建议的更改,但收到了这个错误:
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)'
更新:此问题已解决,只是为了揭示其他(类似)问题。我将采取这里给出的建议继续推进。
答案 0 :(得分:3)
第一个嫌犯:
case (L.null match) of
True -> do
processedDays <- ([(Left $ MkUFD day)] :) <$> flagScheduled rest
return processedDays
也许应该阅读
case (L.null match) of
True -> do
processedDays <- ((Left $ MkUFD day) :) <$> flagScheduled rest
return processedDays
?哦,从写入类型签名开始。这通常会产生更好的错误消息。