1 から までの整数のリストを作成したいと思いますn
。Python では を使用しrange(1, n+1)
、Haskell では: を使用してこれを行うことができますtake n (iterate (1+) 1)
。
これに対する適切な OCaml イディオムは何ですか?
1 から までの整数のリストを作成したいと思いますn
。Python では を使用しrange(1, n+1)
、Haskell では: を使用してこれを行うことができますtake n (iterate (1+) 1)
。
これに対する適切な OCaml イディオムは何ですか?
私が知っているイディオムはありませんが、中置演算子を使用したかなり自然な定義を次に示します。
# 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]
の「コミュニティ バージョン」の将来のリリースに含まれる可能性が高いため、慣用的になる可能性があります。ただし、言語に慣れていない場合は、構文拡張をいじることはお勧めしません。
電池が含まれていると、あなたは書くことができます
let nums = List.of_enum (1--10);;
--
オペレーターは、最初の値から2番目の値までの列挙を生成します。--^
演算子は似ていますが、ハーフオープン間隔を列挙します(11--^10
から9までを列挙します)。
どうぞ:
let rec range i j = if i > j then [] else i :: (range (i+1) j)
これは末尾再帰ではないことに注意してください。最新の Python バージョンには遅延範囲さえあります。
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
ここでゲームに少し遅れますが、ここに私の実装があります:
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 つだけで、完全なフレームワークを避けようとしている場合は、これの方が良いかもしれません。
open Batteries
(標準ライブラリのコミュニティ バージョン)を使用する場合は、次の方法で実行できます( の前のバッククォートに注意してrange(1,n+1)
ください)。List.range 1 `To n
To
より一般的な方法 (バッテリーも必要) は、List.init n f
(f 0) (f 1) ... (f (n-1)) を含むリストを返す を使用することです。