¿Cuál es el idioma OCaml equivalente a la función de rango de Python?

Quiero crear una lista de enteros de 1 a n. Puedo hacer esto en Python usando el rango (1, n + 1), y en Haskell usando: tomar n (iterar (1+) 1).

¿Cuál es el idioma OCaml correcto para esto?

No conozco ningún idioma, pero aquí hay una definición bastante natural con un operador de infijo:

 # let (--) ij = let rec aux n acc = if n < i then acc else aux (n-1) (n :: acc) in aux j [] ;; val ( -- ) : int -> int -> int list =  # 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] 

Alternativamente, la extensión de syntax de comprensión (que proporciona la syntax [i .. j] para la anterior) probablemente se incluya en una versión futura de la “versión comunitaria” de OCaml , por lo que puede volverse idiomática. Sin embargo, no te recomiendo que comiences a jugar con extensiones de syntax si eres nuevo en el idioma.

Con las stacks incluidas , puedes escribir

 let nums = List.of_enum (1--10);; 

El operador -- genera una enumeración del primer valor al segundo. El operador --^ es similar, pero enumera un intervalo medio abierto ( 1--^10 se enumerará de 1 a 9).

Aqui tienes:

 let rec range ij = if i > j then [] else i :: (range (i+1) j) 

Tenga en cuenta que esto no es cola recursiva. Las versiones modernas de Python incluso tienen un rango perezoso.

OCaml tiene una syntax especial para la coincidencia de patrones en rangos:

 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 

Para crear un rango, puedes usar Core :

 List.range 0 1000 

Si usa open Batteries (que es una versión de la comunidad de la biblioteca estándar), puede hacer el range(1,n+1) por List.range 1 `To n (note la cita anterior antes de To ).

Una forma más general (también necesita baterías) es usar List.init nf que devuelve una lista que contiene (f 0) (f 1) … (f (n-1)).

Un poco tarde para el juego aquí, pero aquí está mi implementación:

 let rec range ?(start=0) len = if start >= len then [] else start :: (range len ~start:(start+1)) 

Entonces puedes usarlo muy parecido a la función 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] *) 

naturalmente, creo que la mejor respuesta es simplemente usar Core, pero esto podría ser mejor si solo necesita una función y está tratando de evitar el marco completo.

Esto funciona en base OCaml:

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

Por cierto, en Haskell preferirías usar

 enumFromTo 1 n [1 .. n] 

Estos son simplemente innecesarios.

 take n [1 ..] take n $ iterate (+1) 1 

Si no necesita un parámetro de “paso”, una forma fácil de implementar esta función sería:

let range start stop = List.init (abs @@ stop - start) (fun i -> i + start)