什么是OCaml习惯用语相当于Python的范围函数?

Pra*_*mod 25 python ocaml

我想创建一个从1到n的整数列表.我可以使用range(1,n + 1)在Python中执行此操作,在Haskell中使用:take n(iterate(1+)1).

什么是正确的OCaml成语?

Chr*_*way 25

我不知道有哪些成语,但这是一个使用中缀运算符的相当自然的定义:

# 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]
Run Code Online (Sandbox Code Playgroud)

或者,comprehension语法扩展(提供上述语法[i .. j])可能包含在OCaml"社区版本"的未来版本中,因此可能变得惯用.但是,如果您不熟悉该语言,我建议您不要开始使用语法扩展.


Mic*_*and 13

有了电池,你可以写

let nums = List.of_enum (1--10);;
Run Code Online (Sandbox Code Playgroud)

--操作者产生从所述第一值到所述第二的枚举.的--^操作者是类似的,但是列举了半开区间(1--^10将枚举从1到9).

  • @aneccodeal No. OCaml不允许运算符以'.'开头.(虽然它们可能在第一个字符后包含'.').运算符允许的字符在OCaml的词法文档中定义:http://caml.inria.fr/pub/docs/manual-ocaml/lex.html (2认同)

The*_*ker 11

干得好:

let rec range i j = if i > j then [] else i :: (range (i+1) j)
Run Code Online (Sandbox Code Playgroud)

请注意,这不是尾递归.现代Python版本甚至有一个懒惰的范围.

  • 不完全 - Python范围(1,3)返回[1,2]而你的(范围1 3)返回[1; 2; 3].将>更改为> =. (4认同)
  • @GarkGarcia 当时的“xrange”是生成器版本。 (2认同)

Ale*_*try 9

这适用于基础 OCaml:

? List.init 5 (fun x -> x + 1);; - : int list = [1; 2; 3; 4; 5]


Gar*_*cia 6

如果您打算模拟 的惰性行为range,我实际上建议使用该Stream模块。就像是:

let range (start: int) (step: int) (stop: int): int stream =
    Stream.from (fun i -> let j = i * step + start in if j < stop then Some j else None)
Run Code Online (Sandbox Code Playgroud)

  • 这个答案确实被低估了。我真的很喜欢 Stream 方法。PS.:函数的返回类型应该是`int Stream.t`而不是`int Stream` (2认同)

小智 5

从上面跟随亚历克斯考文垂,但更短。

let range n = List.init n succ;;    
> val range : int -> int list = <fun>   
range 3;;                           
> - : int list = [1; 2; 3]              
Run Code Online (Sandbox Code Playgroud)

  • 谢谢!对于后代来说,“succ”(后继者的缩写)是 OCaml 的 Int 模块的一部分,相当于“((+) 1)”。参考:https://ocaml.org/releases/4.10/htmlman/libref/Int.html (2认同)