在Ocaml中理解列表? [英] List Comprehension in Ocaml?

查看:79
本文介绍了在Ocaml中理解列表?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Ocaml电池似乎具有理解语法: http://en.wikipedia.org/wiki/List_comprehension#OCaml

It seems that Ocaml batteries have comprehension syntax: http://en.wikipedia.org/wiki/List_comprehension#OCaml

但是,我应该包括哪个模块来使用此语法?我已经open Batteries,但是它不起作用.还是有一种更惯用的方式来理解列表?我可以使用List.map和BatList.remove_if来获得类似的结果,但这并不那么优雅.

However, what module should I include to use this syntax? I already open Batteries, but it doesn't work. Or is there a more idiomatic way to do list comprehension? I can use List.map and BatList.remove_if to achieve similar results, but that is much less elegant.

推荐答案

当前,OCaml中有两个提供列表理解的库,一个以前是OCaml电池的一部分,另一个是camlp4附带的.两者都不被广泛使用,我个人不建议您使用任何一种.

Currently there're two libraries in OCaml that provide list comprehension, one was formerly a part of OCaml Batteries, another is shipped with camlp4. Neither is widely used and I, personally, do no recommend you to use any.

要使列表理解功能起作用,您需要更改语言的语法.这可以通过使用camlp4预处理器以扩展的语法对程序进行预处理来完成.另外,列表理解并不是OCaml社区中的一等公民,现代工具包也没有很好地支持列表理解.虽然,您仍然可以轻松地在顶层使用它,但需要安装列表理解包:

For list comprehension to work, you need to change the syntax of the language. This can be done with preprocessing your program, written in an extended syntax, with a camlp4 preprocessor. Also, list comprehension is not a first class citizen in OCaml community, and it is not well supported by the modern toolkits. Although, you can still easily play with it in a toplevel, for that you need, to install the list comprehension package:

opam install pa_comprehension 

并使用以下指令将其加载到顶层:

and load it into a toplevel, using the following directives:

# #use "topfind";;
# #camlp4o;;
# #require "pa_comprehension";;
# open Batteries;;
# [? 2 * x | x <- 0 -- max_int ; x * x > 3 ?];;

但是,再次,我个人认为列表理解并不是构造代码的最佳方法.

But again, my personal opinion that list comprehension is not the best way to structure your code.

您提供的示例可以使用core_kernel Sequence模块(电池Enum的类似物)表示

The example, you provided, can be expressed using core_kernel Sequence module (an analog of the Batteries Enum)

let f n =
  Sequence.(range 0 n |>
            filter ~f:(fun x -> x * x > 3) |>
            map ~f:(fun x -> x * 2))

因此filter |> map是一个常见的习惯用法,就存在一个filter_map函数:

Hence a filter |> map is such a common idiom there exists a filter_map function:

let f n =
  Sequence.(range 0 n |>
            filter_map ~f:(fun x ->
                if x * x > 3 then Some (x * 2) else None))

您可能会注意到,此示例比列表理解需要更多的代码.但是,一旦您的程序开始从具有整数的简单hello world应用程序发展到更复杂的功能,您就会同意使用显式迭代器更加可读和可理解.

You may notice, that this examples takes more code, than list comprehension. But as soon as your programs will start to mature from simple hello world applications with integers to something more sophisticated, you will agree that using explicit iterators is more readable and comprehensible.

此外,由于Core中的库非常一致,因此您可以使用简单的List代替Sequence,只需用前者替换后者即可.但是,当然List很渴望,与Sequence不同,因此使用列表玩max_int并不是一个好主意.

Also, since libraries in Core are so consistent, you can use a simple List instead of Sequence just by substituting the latter by the former. But of course, List is eager, unlike the Sequence, so playing with max_int using lists is not a good idea.

此外,由于所有容器都是monad,因此您可以使用monadic运算符进行映射,例如:

Moreover, since all containers are monads, you can use monadic operators for mapping, like:

let odds n = List.(range 0 n >>| fun x -> x * 2 + 1)

这篇关于在Ocaml中理解列表?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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