2008-10-28 8 views

Antwort

22

Es gibt kein Idiom, die ich kenne, aber hier ist eine ziemlich natürliche Definition mit einem Infixoperator:

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

Alternativ kann die comprehensions syntax extension (die die Syntax [i .. j] für die oben gibt) sein dürfte in einer zukünftigen Version der "community version" of OCaml enthalten, so dass idiomatische werden kann. Ich empfehle Ihnen nicht, mit Syntaxerweiterungen zu spielen, wenn Sie neu in der Sprache sind.

+0

Ihr Link zu der Community ocaml sollte zeigen: http://forge.ocamlcore.org/projects/batteries/ – Thelema

+0

Der '--' Operator ist in den enthaltenen Batterien implementiert, obwohl es eine Enumeration statt einer Liste erzeugt. –

+0

Pythons Bereichsfunktion enthält nicht die obere Grenze, wie Sie, aber einfach genug, um durch den Aufruf von Aux mit (j-1) anstelle von j zu beheben –

10

Hier gehen Sie:

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

Beachten Sie, dass dies nicht Schwanz-rekursiv ist. Moderne Python-Versionen haben sogar einen trägen Bereich.

+3

Nicht ganz - Python-Bereich (1,3) gibt [1,2] zurück, während Ihr (Bereich 1 3) [1; 2; 3] zurückgibt. Wechseln Sie zu> =. –

0

BTW, in Haskell Sie lieber

enumFromTo 1 n 
[1 .. n] 

nur unnötig Dies sind verwenden.

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

Danke, das habe ich nicht bemerkt. – Pramod

11

Mit Batteries Included können Sie

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

Der -- Operator eine Aufzählung von dem ersten Wert auf den zweiten erzeugt. Der Operator --^ ist ähnlich, zählt aber ein halboffenes Intervall auf (1--^10 zählt von 1 bis 9).

+0

Nicht sicher, ich mag - dafür ist es möglich, einen .. Operator zu definieren? – aneccodeal

+1

@aneccodeal Nein. OCaml erlaubt keine Operatoren, die mit '.' (obwohl sie nach dem ersten Zeichen "." enthalten können). Die erlaubten Zeichen für Operatoren sind in der lexikalischen Dokumentation von OCaml definiert: http://caml.inria.fr/pub/docs/manual-ocaml/lex.html –

2

Wenn Sie open Batteries verwenden (das ist eine Community-Version der Standard-Bibliothek ist), können Sie range(1,n+1) von List.range 1 `To n (das Backquote vor To bemerken).

Ein allgemeinerer Weg (auch Batterien brauchen) ist List.init n f, die eine Liste zurückgibt, die (f 0) (f 1) ... (f (n-1)) enthält.

3

OCaml hat spezielle Syntax für den Mustervergleich auf Bereiche:

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 

einen Bereich zu erstellen, können Sie Core verwenden: hier

List.range 0 1000 
2

ein wenig zu spät, um das Spiel, aber hier ist meine Umsetzung:

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

Sie können es dann sehr ähnlich wie die Python-Funktion verwenden:

range 10 
    (* equals: [0; 1; 2; 3; 4; 5; 6; 7; 8; 9] *) 

range ~start:(-3) 3 
    (* equals: [-3; -2; -1; 0; 1; 2] *) 

natürlich denke ich die beste Antwort Core einfach zu verwenden, aber das wäre vielleicht besser, wenn Sie nur eine Funktion benötigen, und Sie versuchen, den vollständigen Rahmen zu vermeiden.