2008-10-28 9 views

Respuesta

22

No hay lenguaje, que yo sepa, pero aquí es una definición bastante natural utilizando un operador infijo:

# 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] 

Alternativamente, el comprehensions syntax extension (que da la sintaxis [i .. j] de lo anterior) es probable que sea incluido en una versión futura del "community version" of OCaml, por lo que puede volverse idiomático. Sin embargo, no recomiendo que comiences a jugar con extensiones de sintaxis si eres nuevo en el lenguaje.

+0

su enlace a la comunidad ocaml debe apuntar a: http://forge.ocamlcore.org/projects/batteries/ – Thelema

+0

El operador '--' se implementa en Baterías incluidas, aunque produce una enumeración en lugar de una lista. –

+0

La función de rango de Python no incluye el límite superior, como el tuyo, pero es fácil de solucionar llamando a aux con (j-1) en lugar de j –

10

Aquí van:

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

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

+3

No del todo - El rango de Python (1,3) devuelve [1,2] mientras que su (rango 1 3) devuelve [1; 2; 3]. Cambiar> a> =. –

0

Por cierto, en Haskell se prefiere utilizar

enumFromTo 1 n 
[1 .. n] 

Estos son sólo innecesaria.

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

Gracias, no me di cuenta de eso. – Pramod

11

Con Batteries Included, puede 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 enumerará del 1 al 9).

+0

No estoy seguro de que me guste - para eso, ¿es posible definir un ... operador? – aneccodeal

+1

@aneccodeal No. OCaml no permite que los operadores comiencen con '.' (aunque pueden contener '.' después del primer carácter). Los caracteres permitidos para los operadores se definen en la documentación léxica de OCaml aquí: http://caml.inria.fr/pub/docs/manual-ocaml/lex.html –

2

Si utiliza open Batteries (que es una versión de la comunidad de la biblioteca estándar), se puede hacer por range(1,n+1)List.range 1 `To n (nótese la comilla inversa antes To).

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

3

OCaml tiene una sintaxis especial para la coincidencia de patrones en los 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 una gama, puede utilizar Core:

List.range 0 1000 
2

Un poco tarde al juego aquí, pero aquí está mi aplicación:

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

Puede 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 sólo se necesita una función y que está tratando de evitar que el marco completo.

Cuestiones relacionadas