Haskell 在两个输入列表上映射函数
我想用几组输入测试一个函数。假设函数是Haskell 在两个输入列表上映射函数,haskell,Haskell,我想用几组输入测试一个函数。假设函数是 f :: a -> b -> c 现在我有两个输入列表: inputA :: [a] inputB :: [[b]] 对于inputA!!我,我要计算f$input!!列表中的每个元素的i位于inputB!!我。我知道我需要几个map应用程序才能做到这一点,但我很难找到解决方案 我最近的尝试是 map f inputA <$> inputB 我认为这是正确的方向。现在我需要将每个函数映射到inputB中的每个输入列表上 为了澄
f :: a -> b -> c
现在我有两个输入列表:
inputA :: [a]
inputB :: [[b]]
对于inputA!!我
,我要计算f$input!!列表中的每个元素的i
位于inputB!!我
。我知道我需要几个map
应用程序才能做到这一点,但我很难找到解决方案
我最近的尝试是
map f inputA <$> inputB
我认为这是正确的方向。现在我需要将每个函数映射到inputB
中的每个输入列表上
为了澄清,我想将
map f inputA
中的I
th函数映射到inputB
中的I
th输入列表,以获得结果outputUTC::[[c]]]
如果我理解正确,比如:
mapNested::(a->b->c)->[a]->[[b]]->[[c]]
MapF[].[]
MAPF[]=[]
mapNested f(x:xs)ys=concatMap(map(fx))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]]
映射嵌套f xs=zipWith映射(映射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)]]
如果我理解正确,这就是您需要的:
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>
i、 e
您可以使用
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]]
通过列表理解,一切都很简单
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
您似乎也在尝试寻找它的无点版本:
= zipWith (map . f) xs yss
= (zipWith . (map .)) f xs yss
因此,通过eta减少g=(zipWith.(map.))
,但这可能不容易理解。这进一步被混淆为zipWith(map)
甚至zipWith(())
或者,我们可以使用
=zipWith(map.f)xs-yss
=getZipList$liftA2(map.f)(ZipList xs)(ZipList yss)
=getZipList$pure(map.f)ZipList xs ZipList yss
=getZipList$(map.f)ZipList xs ZipList yss
=getZipList$map(f ZipList xs)ZipList yss
这几乎就是我想要的。但是,以您的示例为例,我希望在第一个列表的元素中添加1,在第二个列表中添加2,在第三个列表中添加3,而不是在每个列表的所有元素中添加每个数字。您将获得第一个回答的复选标记。在看到您使用的zipWith
之后,这一点似乎非常明显(特别是因为我已经在其他一些相关上下文中使用了zipWith
)。如果您还没有看到,您可能还会对它感兴趣。@DanielWagner感谢您的链接。我已经非常简单地阅读了QuickCheck,它在我要了解Haskell的事情列表中。一个较短的版本:fancyZipMap f=zipWith$map。f
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
map c' $ zip a b == zipWith c a b where c' (a,b) = 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
= zipWith (map . f) xs yss
= getZipList $ liftA2 (map . f) (ZipList xs) (ZipList yss)
= getZipList $ pure (map . f) <*> ZipList xs <*> ZipList yss
= getZipList $ (map . f) <$> ZipList xs <*> ZipList yss
= getZipList $ map <$> (f <$> ZipList xs) <*> ZipList yss