Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 在两个输入列表上映射函数_Haskell - Fatal编程技术网

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