为什么期望 (String, Int) 而不是 (Char, Int)?
Why (String, Int) is expected instead of (Char, Int)?
我完全不知道为什么以下方法不起作用:
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 的答案。
Why a String is expected, when zip will clearly "disunite" the string into individual characters?
因为 read
需要一个字符串。为了将单个数字转换为整数,请使用 digitToInt
,而不是 read
(或者您也可以使用 read [theChar]
来创建一个单字符字符串并将其转换,但没有必要因为这里 digitToInt
存在)。
PS:代替snd x
和snd pair
,使用模式匹配来单独命名对的元素会更加惯用。
您正在映射的函数 read . fst
具有类型 Read a => (String, b) -> a
。所以map (read . fst) :: Read a => [(String, b)] -> [a]
。但是 zipped
具有 [(Char, Int)]
类型,并且 takeRange
returns 与输入的列表类型相同。
顺便说一句,您可以将 takeRange
实现为
takeRange n elem list = take n $ drop (snd elem) $ list
您正在通过手动计算索引来做额外的工作,正如@sepp2k 提到的那样,这对于元组上的模式匹配会更加惯用。
我完全不知道为什么以下方法不起作用:
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 的答案。
Why a String is expected, when zip will clearly "disunite" the string into individual characters?
因为 read
需要一个字符串。为了将单个数字转换为整数,请使用 digitToInt
,而不是 read
(或者您也可以使用 read [theChar]
来创建一个单字符字符串并将其转换,但没有必要因为这里 digitToInt
存在)。
PS:代替snd x
和snd pair
,使用模式匹配来单独命名对的元素会更加惯用。
您正在映射的函数 read . fst
具有类型 Read a => (String, b) -> a
。所以map (read . fst) :: Read a => [(String, b)] -> [a]
。但是 zipped
具有 [(Char, Int)]
类型,并且 takeRange
returns 与输入的列表类型相同。
顺便说一句,您可以将 takeRange
实现为
takeRange n elem list = take n $ drop (snd elem) $ list
您正在通过手动计算索引来做额外的工作,正如@sepp2k 提到的那样,这对于元组上的模式匹配会更加惯用。