我有一個函數太複雜,我不明白函數類型應該是什麼。我試圖讓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
小號迭代。 其他功能將改變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 }
你看到那裏發生了什麼?以下是我所做的更改。在傳遞給return
之前,我通過了processedDays
到concat
。
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)'
更新:這個問題已經解決了,只露出其他(類似)的問題。我要接受這裏給出的建議來推進。
我強烈地將其分解爲幾個較短的函數 - 當情況發生變化時,它們將更容易測試,更容易維護並更容易適應。 –
嘿,這是一些很好的輔助......「更容易測試/更容易維護/更容易適應環境變化!」這將成爲我的口頭禪。 –