31

1 から までの整数のリストを作成したいと思いますn。Python では を使用しrange(1, n+1)、Haskell では: を使用してこれを行うことができますtake n (iterate (1+) 1)

これに対する適切な OCaml イディオムは何ですか?

4

13 に答える 13

26

私が知っているイディオムはありませんが、中置演算子を使用したかなり自然な定義を次に示します。

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

あるいは、内包構文拡張(上記の構文を提供する) は、OCaml[i .. j]の「コミュニティ バージョン」の将来のリリースに含まれる可能性が高いため、慣用的になる可能性があります。ただし、言語に慣れていない場合は、構文拡張をいじることはお勧めしません。

于 2008-10-28T17:13:42.967 に答える
13

電池が含まれていると、あなたは書くことができます

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

--オペレーターは、最初の値から2番目の値までの列挙を生成します。--^演算子は似ていますが、ハーフオープン間隔を列挙します(11--^10から9までを列挙します)。

于 2010-05-28T01:33:00.953 に答える
11

どうぞ:

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

これは末尾再帰ではないことに注意してください。最新の Python バージョンには遅延範囲さえあります。

于 2008-10-28T17:07:22.980 に答える
3

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

範囲を作成するには、次を使用できますCore

List.range 0 1000
于 2015-10-07T19:25:48.543 に答える
2

ここでゲームに少し遅れますが、ここに私の実装があります:

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

その後、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] *)

当然のことながら、最善の答えは単純に Core を使用することだと思いますが、必要な関数が 1 つだけで、完全なフレームワークを避けようとしている場合は、これの方が良いかもしれません。

于 2016-03-19T05:41:34.317 に答える
2

open Batteries(標準ライブラリのコミュニティ バージョン)を使用する場合は、次の方法で実行できます( の前のバッククォートに注意してrange(1,n+1)ください)。List.range 1 `To nTo

より一般的な方法 (バッテリーも必要) は、List.init n f(f 0) (f 1) ... (f (n-1)) を含むリストを返す を使用することです。

于 2014-12-28T06:33:31.277 に答える