Haskell列表理解顺序元素/元组

时间:2018-05-07 18:51:49

标签: haskell functional-programming list-comprehension

我目前正在学习Haskell,在FP方面我是一个绝对的初学者。

现在我正在尝试使用列表推导的不同内容。

 listComprehension  = [(a,b,c) | a <- xs, b <- xs, c <- ys, even c, c == a+b] ++
                      [(a,b,c) | a <- xs, b <- xs, c <- ys, even c, c == a-b]
                      where xs = [1..4]; ys = [(-100)..100]

为什么不说:

 listComprehension  = [(a,b,c) | a <- xs, b <- xs, c <- ys, even c, c == a+b || c == a-b]
                      where xs = [1..4]; ys = [(-100)..100]

我希望元素的排序方式与我的第一个例子完全相同。 我想要所有元素,其中c = a + b,然后是所有元素,其中c = a-b。

请注意,在我的第二个代码中,订单不是我想要的。我似乎无法弄清楚我是如何在列表理解中命令的,特别是当我有元组时...

谢谢!

2 个答案:

答案 0 :(得分:6)

在第一个生成器中选择函数Welcome to the Google Cloud SDK! To help improve the quality of this product, we collect anonymized usage data and anonymized stacktraces when crashes are encountered; additional information is available at <https://cloud.google.com/sdk/usage-statistics>. You may choose to opt out of this collection now (by choosing 'N' at the below prompt), or at any time in the future by running the following command: gcloud config set disable_usage_reporting true Do you want to help improve the Google Cloud SDK (Y/n)? Y Traceback (most recent call last): File "/Users/<user>/Downloads/google-cloud-sdk/bin/bootstrapping/install.py", line 218, in <module> main() File "/Users/<user>/Downloads/google-cloud-sdk/bin/bootstrapping/install.py", line 196, in main Install(pargs.override_components, pargs.additional_components) File "/Users/<user>/Downloads/google-cloud-sdk/bin/bootstrapping/install.py", line 141, in Install _CLI.Execute(['--quiet', 'components', 'list']) File "/Users/<user>/Downloads/google-cloud-sdk/lib/googlecloudsdk/calliope/cli.py", line 870, in Execute self._HandleAllErrors(exc, command_path_string, specified_arg_names) File "/Users/<user>/Downloads/google-cloud-sdk/lib/googlecloudsdk/calliope/cli.py", line 908, in _HandleAllErrors exceptions.HandleError(exc, command_path_string, self.__known_error_handler) File "/Users/<user>/Downloads/google-cloud-sdk/lib/googlecloudsdk/calliope/exceptions.py", line 526, in HandleError core_exceptions.reraise(exc) File "/Users/<user>/Downloads/google-cloud-sdk/lib/googlecloudsdk/core/exceptions.py", line 111, in reraise six.reraise(type(exc_value), exc_value, tb) File "/Users/<user>/Downloads/google-cloud-sdk/lib/googlecloudsdk/calliope/cli.py", line 844, in Execute resources = calliope_command.Run(cli=self, args=args) File "/Users/<user>/Downloads/google-cloud-sdk/lib/googlecloudsdk/calliope/backend.py", line 756, in Run resources = command_instance.Run(args) File "/Users/<user>/Downloads/google-cloud-sdk/lib/surface/components/list.py", line 98, in Run only_local_state=args.only_local_state) File "/Users/<user>/Downloads/google-cloud-sdk/lib/googlecloudsdk/core/updater/update_manager.py", line 674, in List to_print, current_version, latest_version = self._GetPrintListWithDiff() File "/Users/<user>/Downloads/google-cloud-sdk/lib/googlecloudsdk/core/updater/update_manager.py", line 704, in _GetPrintListWithDiff _, diff = self._GetStateAndDiff(command_path='components.list') File "/Users/<user>/Downloads/google-cloud-sdk/lib/googlecloudsdk/core/updater/update_manager.py", line 600, in _GetStateAndDiff command_path=command_path) File "/Users/<user>/Downloads/google-cloud-sdk/lib/googlecloudsdk/core/updater/update_manager.py", line 583, in _GetLatestSnapshot *effective_url.split(','), command_path=command_path) File "/Users/<user>/Downloads/google-cloud-sdk/lib/googlecloudsdk/core/updater/snapshots.py", line 178, in FromURLs for url in urls] File "/Users/<user>/Downloads/google-cloud-sdk/lib/googlecloudsdk/core/updater/snapshots.py", line 199, in _DictFromURL response = installers.ComponentInstaller.MakeRequest(url, command_path) File "/Users/<user>/Downloads/google-cloud-sdk/lib/googlecloudsdk/core/updater/installers.py", line 293, in MakeRequest return ComponentInstaller._RawRequest(req, timeout=timeout) File "/Users/<user>/Downloads/google-cloud-sdk/lib/googlecloudsdk/core/updater/installers.py", line 337, in _RawRequest should_retry_if=RetryIf, sleep_ms=500) File "/Users/<user>/Downloads/google-cloud-sdk/lib/googlecloudsdk/core/util/retry.py", line 178, in RetryOnException exceptions.reraise(exc_info[1], tb=exc_info[2]) File "/Users/<user>/Downloads/google-cloud-sdk/lib/googlecloudsdk/core/exceptions.py", line 111, in reraise six.reraise(type(exc_value), exc_value, tb) File "/Users/<user>/Downloads/google-cloud-sdk/lib/googlecloudsdk/core/util/retry.py", line 159, in TryFunc return func(*args, **kwargs), None File "/Users/<user>/Downloads/google-cloud-sdk/lib/googlecloudsdk/core/url_opener.py", line 78, in urlopen return opener.open(req, data, timeout) File "/usr/local/Cellar/python@2/2.7.14_3/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 429, in open response = self._open(req, data) File "/usr/local/Cellar/python@2/2.7.14_3/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 447, in _open '_open', req) File "/usr/local/Cellar/python@2/2.7.14_3/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 407, in _call_chain result = func(*args) File "/Users/<user>/Downloads/google-cloud-sdk/lib/googlecloudsdk/core/url_opener.py", line 63, in https_open return self.do_open(build, req) File "/usr/local/Cellar/python@2/2.7.14_3/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.py", line 1195, in do_open h.request(req.get_method(), req.get_selector(), req.data, headers) File "/usr/local/Cellar/python@2/2.7.14_3/Frameworks/Python.framework/Versions/2.7/lib/python2.7/httplib.py", line 1042, in request self._send_request(method, url, body, headers) File "/usr/local/Cellar/python@2/2.7.14_3/Frameworks/Python.framework/Versions/2.7/lib/python2.7/httplib.py", line 1082, in _send_request self.endheaders(body) File "/usr/local/Cellar/python@2/2.7.14_3/Frameworks/Python.framework/Versions/2.7/lib/python2.7/httplib.py", line 1038, in endheaders self._send_output(message_body) File "/usr/local/Cellar/python@2/2.7.14_3/Frameworks/Python.framework/Versions/2.7/lib/python2.7/httplib.py", line 882, in _send_output self.send(msg) File "/usr/local/Cellar/python@2/2.7.14_3/Frameworks/Python.framework/Versions/2.7/lib/python2.7/httplib.py", line 844, in send self.connect() File "/Users/<user>/Downloads/google-cloud-sdk/lib/third_party/httplib2/python2/httplib2/__init__.py", line 1120, in connect raise SSLHandshakeError(e) httplib2.python2.httplib2.SSLHandshakeError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:661)

(+),(-)

顺便说一句,这是一种效率低下的方法。我们不应该尝试每个listComprehension = [(a,b,c) | f <- [(+),(-)], a <- xs, b <- xs, c <- ys, even c, c == f a b ] where xs = [1..4]; ys = [(-100)..100] ,而应该c <- ys,然后检查let c = f a b(和均匀度)。我们以这种方式使代码快200倍。

答案 1 :(得分:0)

之前我已经在列表推导中使用了替代函数([even,odd])。我并不总是对他们最有效率感到满意。我看到的缺点是他们会通过源列表进行两次或多次传递。为此,我选择了不同的方法,但是,对于较小的数据集,效率并不是很重要。

这就是我写的

lc xs ys = [[(a,b,c)|(a,b,c)<-ls,c==a+b] ++ [(a,b,c)|(a,b,c)<-ls,c==a-b]]
           where ls = [(a,b,c)| a<-xs, b<-xs, c<-ys, even c]

这比原来的功能更快,比其他答案更快。更引人注目的是它使用的内存比其中任何一个都少。

从长列表中选择值是另一回事,而从生成的值中设置它们是另一回事。

lc xs = [(a,b,c)|a<-xs,b<-xs,c<-[(a-b),(a+b)],even c]
partition (\(a,b,c) -> c == a+b) lc [1..4]