我只是想逐个元素地将两个列表相乘,所以我将(*)作为该函数的第一个参数传递:
apply :: Num a => (a -> a -> a) -> [a] -> [a] -> [a]
apply f xs ys = [f (xs !! i) (ys !! i) | i <- [0..(length xs - 1)]]
我可能会问一个愚蠢的问题,但我实际上搜索了很多,但却找不到。谢谢你们,伙计们!
答案 0 :(得分:10)
> :t zipWith
zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
> zipWith (*) [1,2,3] [4,5,6]
[4,10,18]
这是Hoogle在使用您的类型
查询时提供的第八个结果(a -> a -> a) -> [a] -> [a] -> [a]
此外,当您需要实现自己的功能时,仅使用list !! index
作为最后的手段,因为它通常会导致性能不佳,成本为O(index)
。同样,只有在必要时才应使用length
,因为它需要扫描整个列表。
在zipWith
案例中,您可以避免这两种情况并以自然方式递归递归:它大致实现为
zipWith _ [] _ = []
zipWith _ _ [] = []
zipWith f (x:xs) (y:ys) = f x y : zipWith f xs ys
请注意,这只会尽可能多地递归到达最短列表的末尾。较长列表的剩余部分将被丢弃。