我完全失去了为什么以下不起作用:
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的答案。
答案 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 x
和snd pair
,而不是惯用语。