使用具有两个列表而非一个列表的地图。你可以窝窝吗? [英] Using map with two lists rather than one. Can you nest?

查看:116
本文介绍了使用具有两个列表而非一个列表的地图。你可以窝窝吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要运行一个多次使用两个参数的函数。我有两个包含这些参数的列表,我希望能够使用 map 或类似的东西来调用具有相应参数的函数。



我想要调用的函数有这样的类型:

  runParseTest :: String  - >字符串 - > IO()

这些列表是这样创建的:

   - 获取库目录中的文件列表
文件< - getDirectoryContentstests / libraries
- 过滤掉..和 。并添加路径
let names = filter(\ x - > head x / ='。')files
let libs = [tests / libraries /++ f | f < - $ name>

因此可以说名称包含 [test1.js,test2.js,test3.js] libs 包含 [tests / libraries / test1.js,tests / libraries / test2.js,tests / libraries / test3.js]



我想这样称呼他们:

  runParseTesttest1.js tests / libraries / test1.js
runParseTesttest2.jstests / libraries / test2.js
runParseTesttest3.jstests / libraries / test3.js

我知道我可以创建一个辅助函数,它可以很容易地完成这项工作,但出于兴趣,是否可以在一行使用 map



这是我迄今为止的内容,但显然第一个参数始终是test :

  mapM_(runParseTesttest)libs 

如果不清楚,我很抱歉。我可以提供更多的信息,如果有必要的话。

解决方案


c> [test1.js,test2.js,test3.js]
和libs包含 [tests / libraries / test1.js ,tests / libraries / test2.js,tests / libraries / test3.js]



我想给他们打电话这:

runParseTesttest1.jstests / libraries / test1.js
runParseTesttest2.jstests / libraries / test2.js
runParseTesttest3.jstests / libraries / test3。 js


可以用 zip

$ $ p $ map(\(a,b) - > runParseTest ab)$ zip名称库lib

也许 uncurry runParseTest

  map(uncurry runParseTest)$ zip名称库

或与 zipWith

  zipWith runParseTest names libs 

Ozgur 表示,monads有一些类似物:

 > :t zipWithM 
zipWithM :: Monad m => (a - > b - > m c) - > [a] - > [b] - > m [c]
> :t zipWithM_
zipWithM_ :: Monad m => (a - > b - > m c) - > [a] - > [b] - > m()


I need to run a function that takes two arguments several times. I have two lists containing these arguments and I'd like to be able to use map or something similar to call the function with the corresponding args.

The function I want to call has this type:

runParseTest :: String -> String -> IO()

The lists are created like this:

-- Get list of files in libraries directory
files <- getDirectoryContents "tests/libraries"
-- Filter out ".." and "." and add path
let names = filter (\x -> head x /= '.') files
let libs = ["tests/libraries/" ++ f | f <- names]

So lets say that names contains ["test1.js", "test2.js", "test3.js"] and libs contains ["tests/libraries/test1.js", "tests/libraries/test2.js", "tests/libraries/test3.js"]

I want to call them like this:

runParseTest "test1.js" "tests/libraries/test1.js"
runParseTest "test2.js" "tests/libraries/test2.js"
runParseTest "test3.js" "tests/libraries/test3.js"

I know I could create a helper function that does this fairly easily, but out of interest, is it possible to do in one line using map?

This is what I have so far, but obviously the first argument is always "test":

mapM_ (runParseTest "test") libs

I apologise if this is unclear. I can provide more info if necessary.

解决方案

So lets say that names contains ["test1.js", "test2.js", "test3.js"] and libs contains ["tests/libraries/test1.js", "tests/libraries/test2.js", "tests/libraries/test3.js"]

I want to call them like this:

runParseTest "test1.js" "tests/libraries/test1.js" runParseTest "test2.js" "tests/libraries/test2.js" runParseTest "test3.js" "tests/libraries/test3.js"

It's possible to do that with zip:

map (\(a,b) -> runParseTest a b) $ zip names libs

Or maybe uncurry runParseTest:

 map (uncurry runParseTest) $ zip names libs

Or with zipWith:

 zipWith runParseTest names libs

And like Ozgur said, there are some analogues for monads:

> :t zipWithM
zipWithM :: Monad m => (a -> b -> m c) -> [a] -> [b] -> m [c]
> :t zipWithM_
zipWithM_ :: Monad m => (a -> b -> m c) -> [a] -> [b] -> m ()

这篇关于使用具有两个列表而非一个列表的地图。你可以窝窝吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆