2015-05-15 122 views
0

我完全失去了爲什麼下面不工作:爲什麼(字符串,詮釋)預期而不是(字符,詮釋)?

takeRange :: Int -> (a,Int) -> [(a,Int)] -> [(a,Int)] 
takeRange n elem list = dropWhile (\x -> snd x < snd elem) (takeWhile (\x -> snd x < (snd elem) + n) list) 

seriesLargestProd :: String -> Int -> Int 
seriesLargestProd "" _ = 0 
seriesLargestProd _ 0 = 0 
seriesLargestProd s n = maximum [foldl1 (*) $ map (read . fst) (takeRange n pair zipped) 
           | pair <- zipped, snd pair <= lastStartingIndex] 
            where zipped = zip s [1..] 
              lastStartingIndex = (length s) - (n-1) 

錯誤消息我得到:

Couldn't match type `Char' with `[Char]' 
    Expected type: (String, Int) 
     Actual type: (Char, Int) 
    In the second argument of `takeRange', namely `pair' 
    In the second argument of `map', namely `(takeRange n pair zipped)' 

Couldn't match type `Char' with `[Char]' 
    Expected type: [(String, Int)] 
     Actual type: [(Char, Int)] 
    In the third argument of `takeRange', namely `zipped' 
    In the second argument of `map', namely `(takeRange n pair zipped)' 

如果任何人的興趣,這應該是一個答案問題8的Project Euler

回答

3

您映射的函數read . fst的類型爲Read a => (String, b) -> a。所以map (read . fst) :: Read a => [(String, b)] -> [a]。但zipped的類型爲[(Char, Int)],並且takeRange返回與其輸入相同類型的列表。

順便說一句,你可以實現takeRange作爲

takeRange n elem list = take n $ drop (snd elem) $ list 

你通過手動計數的指標做額外的工作,並作爲@ sepp2k提到這將是更地道與元組模式匹配。

+0

謝謝你的回答。這真的很有幫助。 – Kapol

2

爲什麼一個字符串是預期的,當壓縮將明顯「分裂」字符串成個別字符?

因爲read需要一個字符串。爲了將一個數字轉換爲一個整數,使用digitToInt而不是read(或者,您也可以使用read [theChar]創建一個單字符字符串並將其轉換,但由於存在digitToInt,因此不需要這樣做)。

PS:代替snd xsnd pair,使用模式匹配來單獨指定對的元素會更加通俗。

+0

我已經刪除了引用的部分。對不起。 – Kapol

相關問題