期望为什么(String,Int)而不是(Char,Int)?

时间:2015-05-15 20:27:07

标签: haskell list-comprehension

我完全失去了为什么以下不起作用:

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)'

如果有人感兴趣,这应该是Project Euler问题8的答案。

2 个答案:

答案 0 :(得分: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提到这对于元组上的模式匹配更加惯用。

答案 1 :(得分:2)

  

为什么会出现一个字符串,当zip显然是&#34; disunite&#34;将字符串转换为单个字符?

因为read接受一个字符串。要将单个数字转换为整数,请使用digitToInt,而不是read(或者您也可以使用read [theChar]创建单个字符的字符串并对其进行转换,但在那里&#39 ;这里不需要digitToInt存在)。

PS:使用模式匹配来单独命名对的元素,而不是snd xsnd pair,而不是惯用语。