我有一个功能,我想用几组输入进行测试。让我们说功能是
f :: a -> b -> c
现在我有两个输入列表:
inputA :: [a]
inputB :: [[b]]
对于inputA !! i
,我想为f $ input !! i
列表中的每个元素评估inputB !! i
。我知道我需要map
的几个应用程序才能做到这一点,但我很难绕过解决方案。
我最近的尝试是
map f inputA <$> inputB
会出现以下错误:
无法匹配预期类型
a0 -> b0' with actual type
[b1]&#39;
在map'
地图&#39;的调用的返回类型中适用于太多的论点
Probable cause:
在(<$>)', namely
map f inputA&#39;的第一个参数中 在表达式中:map f inputA inputB
我应该如何解决这个问题?我不一定想要一个完整的解决方案。一个有用的方向推(或甚至推)肯定会受到赞赏。
其他想法:
map f inputA :: [b -> c]
我认为这是正确的方向。现在我需要在inputB
。
为了澄清,我想将i
map f inputA
函数映射到i
的{{1}}输入列表中,以获得结果inputB
答案 0 :(得分:6)
您可以使用zipWith
Prelude> let a = [1,2,3]
Prelude> let b = [[1,2,3],[4,5,6],[7,8,9]]
Prelude> zipWith (\a' bl -> map (+a') bl) a b
[[2,3,4],[6,7,8],[10,11,12]]
答案 1 :(得分:2)
列表推导一切都很简单:
g f xs yss = [ [f x y | y <- ys] | (x,ys) <- zip xs yss]
= [ map (f x) ys | (x,ys) <- zip xs yss]
= [ map fx ys | (fx,ys) <- zip (map f xs) yss]
= zipWith map (map f xs) yss
= [ (map . f) x ys | (x,ys) <- zip xs yss]
= zipWith (map . f) xs yss
nponeccop在评论中首先显示的最后一个,并在其他答案中暗示;我们可以通过使用代码转换来获取它
map c $ zip a b == zipWith c a b
map (c a) b == (map . c) a b
\a b-> map (c a) b == map . c
似乎你也试图找到它的无点版本:
= zipWith (map . f) xs yss
= (zipWith . (map .)) f xs yss
所以通过eta-reduction g = (zipWith . (map .))
,但这可能不容易理解。这被进一步混淆为zipWith <$> (map <$>)
甚至zipWith <$> ((<$>) <$>)
。
或者,我们可以使用the ZipList
type from Control.Applicative
作为
= zipWith (map . f) xs yss
= getZipList $ pure (map . f) <*> ZipList xs <*> ZipList yss
= getZipList $ (map . f) <$> ZipList xs <*> ZipList yss
= getZipList $ map <$> (f <$> ZipList xs) <*> ZipList yss
答案 2 :(得分:1)
如果我正确理解你,可以这样:
mapNested :: (a -> b -> c) -> [a] -> [[b]] -> [[c]]
mapNested f [] _ = []
mapNested f _ [] = []
mapNested f (x:xs) ys = concatMap (map (f x)) ys : mapNested f xs ys
Main> mapNested (+) [1, 2, 3] [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
[[2,3,4,5,6,7,8,9,10],[3,4,5,6,7,8,9,10,11],[4,5,6,7,8,9,10,11,12]]
如果这不是你想要的,你能提供一个示例输入和输出吗?
修改强>
或者这就是你想要的?
mapNested :: (a -> b -> c) -> [a] -> [[b]] -> [[c]]
mapNested f xs = zipWith map (map f xs)
Main> mapNested (,) [1, 2, 3] [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
[[(1,1),(1,2),(1,3)],[(2,4),(2,5),(2,6)],[(3,7),(3,8),(3,9)]]
答案 3 :(得分:1)
如果我理解正确,这就是你需要的:
Prelude> let f x y = x + y
Prelude> let xs = [1, 2, 3, 4, 5]
Prelude> let ys = [[1, 2], [3, 4, 5], [6, 7], [8], [9, 10]]
Prelude> map (\(x, ys) -> map (f x) ys) $ zip xs ys
[[2,3],[5,6,7],[9,10],[12],[14,15]]
Prelude>
即
fancyZipMap :: (a -> b -> c) -> [a] -> [[b]] -> [[c]]
fancyZipMap f xs yys = map (\(x, ys) -> map (f x) ys) $ zip xs yys