实现
oddPairs :: [Int] -> [Int] -> [(Int, Int)]
函数,该函数返回一对列表,但仅当参数' lists'各自元素的和为奇数时。例如:
oddPairs [1,2,3] [2,2,2] == [(1,2),(3,2)]
oddPairs [1,3,5] [2,4,6] == zip [1,3,5] [2,4,6]
oddPairs [1,2,3] [1,2,3] == []
到目前为止,我已经尝试了
oddPairs (x:xs) (y:ys) | (x+y) `mod` 2 == 0 = []
| (x+y) `mod` 2 /= 0 = [(x, y)] ++ oddPairs (xs) (ys)
在第一个例子中,它只返回[(1,2)]
,在第二个例子中,它返回正确的值,但Non-exhaustive patterns
错误。
如果两项相等,则不应该只返回空列表,而应该继续递归,直到至少有一个列表耗尽,因此:
oddPairs :: Integral a => [a] -> [a] -> [(a, a)]
oddPairs [] _ = []
oddPairs _ [] = []
oddPairs (x:xs) (y:ys)
-- keep searching for new items ↓
| (x+y) `mod` 2 == 0 =oddPairs xs ys
| otherwise = (x, y) : oddPairs xs ys
另一种看待问题的方式是,您只希望对它们的和是奇数。这是一个重点上的细微差别,可能会导致以下情况:
使用zip
函数将每个列表组合成对。然后用filter
找出奇数和
oddPairs :: Integral a => [a] -> [a] -> [(a, a)]
oddPairs f s = filter oddPair (zip f s)
where oddPair (l, r) = not $ even (l + r)
非常直接地使用列表推导式:
oddPairs :: [Int] -> [Int] -> [(Int, Int)]
oddPairs ms ns = [(m, n) | (m, n) <- zip ms ns, odd (m + n)]
确实:
> oddPairs [1, 2, 3] [2, 2, 2] == [(1, 2),(3, 2)]
True
> oddPairs [1, 3, 5] [2, 4, 6] == zip [1, 3, 5] [2, 4, 6]
True
> oddPairs [1, 2, 3] [1, 2, 3] == []
True