与 Python 的 range 函数等效的 OCaml 成语是什么?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/243864/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What is the OCaml idiom equivalent to Python's range function?
提问by Pramod
I want to create a list of integers from 1 to n. I can do this in Python using range(1, n+1), and in Haskell using: take n (iterate (1+) 1).
我想创建一个从 1 到 n 的整数列表。我可以在 Python 中使用 range(1, n+1) 来做到这一点,在 Haskell 中使用:take n (iterate (1+) 1)。
What is the right OCaml idiom for this?
什么是正确的 OCaml 习语?
采纳答案by Chris Conway
There is no idiom that I know of, but here is a fairly natural definition using an infix operator:
我不知道任何习语,但这里有一个使用中缀运算符的相当自然的定义:
# let (--) i j =
let rec aux n acc =
if n < i then acc else aux (n-1) (n :: acc)
in aux j [] ;;
val ( -- ) : int -> int -> int list = <fun>
# 1--2;;
- : int list = [1; 2]
# 1--5;;
- : int list = [1; 2; 3; 4; 5]
# 5--10;;
- : int list = [5; 6; 7; 8; 9; 10]
Alternatively, the comprehensions syntax extension(which gives the syntax [i .. j]
for the above) is likely to be included in a future release of the "community version" of OCaml, so that may become idiomatic. I don't recommend you start playing with syntax extensions if you are new to the language, though.
或者,理解语法扩展(提供上述语法[i .. j]
)很可能包含在OCaml的“社区版本”的未来版本中,因此这可能会成为惯用语。但是,如果您不熟悉该语言,我不建议您开始使用语法扩展。
回答by Michael Ekstrand
With Batteries Included, you can write
随着电池包括,你可以写
let nums = List.of_enum (1--10);;
The --
operator generates an enumeration from the first value to the second. The --^
operator is similar, but enumerates a half-open interval (1--^10
will enumerate from 1 through 9).
的--
操作者产生从所述第一值到所述第二的枚举。的--^
操作者是类似的,但是列举了半开区间(1--^10
将枚举从1到9)。
回答by Thedric Walker
Here you go:
干得好:
let rec range i j = if i > j then [] else i :: (range (i+1) j)
Note that this is not tail-recursive. Modern Python versions even have a lazy range.
请注意,这不是尾递归。现代 Python 版本甚至有一个惰性范围。
回答by Alex Coventry
This works in base OCaml:
这适用于基础 OCaml:
# List.init 5 (fun x -> x + 1);;
- : int list = [1; 2; 3; 4; 5]
# List.init 5 (fun x -> x + 1);;
- : int list = [1; 2; 3; 4; 5]
回答by Matthias Braun
OCaml has special syntax for pattern matching on ranges:
OCaml 具有用于范围匹配模式的特殊语法:
let () =
let my_char = 'a' in
let is_lower_case = match my_char with
| 'a'..'z' -> true (* Two dots define a range pattern *)
| _ -> false
in
printf "result: %b" is_lower_case
To create a range, you can use Core
:
要创建范围,您可以使用Core
:
List.range 0 1000
回答by JustGage
A little late to the game here but here's my implementation:
这里的游戏有点晚了,但这是我的实现:
let rec range ?(start=0) len =
if start >= len
then []
else start :: (range len ~start:(start+1))
You can then use it very much like the python function:
然后,您可以像使用 python 函数一样使用它:
range 10
(* equals: [0; 1; 2; 3; 4; 5; 6; 7; 8; 9] *)
range ~start:(-3) 3
(* equals: [-3; -2; -1; 0; 1; 2] *)
naturally I think the best answer is to simply use Core, but this might be better if you only need one function and you're trying to avoid the full framework.
自然我认为最好的答案是简单地使用 Core,但是如果您只需要一个功能并且您试图避免使用完整的框架,这可能会更好。
回答by user69818
If you use open Batteries
(which is a community version of the standard library), you can do range(1,n+1)
by List.range 1 `To n
(notice the backquote before To
).
如果你使用open Batteries
(这是标准库的社区版本),你可以range(1,n+1)
通过List.range 1 `To n
(注意前面的反引号To
)。
A more general way (also need batteries) is to use List.init n f
which returns a list containing (f 0) (f 1) ... (f (n-1)).
更通用的方法(也需要电池)是使用List.init n f
它返回一个包含 (f 0) (f 1) ... (f (n-1)) 的列表。
回答by Travis S
Following on Alex Coventry from above, but even shorter.
从上面跟随亚历克斯考文垂,但更短。
let range n = List.init n succ;;
> val range : int -> int list = <fun>
range 3;;
> - : int list = [1; 2; 3]
回答by Nondv
Came up with this:
想出了这个:
let range a b =
List.init (b - a) ((+) a)
回答by Gark Garcia
If you intend to emulate the lazy behavior of range
, I would actually recommend using the Stream
module. Something like:
如果您打算模拟 的惰性行为range
,我实际上建议使用该Stream
模块。就像是:
let range (start: int) (step: int) (stop: int): int stream =
Stream.from (fn i -> let j = i * step + start in if j < stop then Some j else None)