Pythonの範囲関数に相当する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]
または、 comprehensions構文拡張(構文 [i .. j]
は上記の「コミュニティバージョン」」 OCaml のようになります。ただし、言語を初めて使用する場合は、構文拡張機能を使用することはお勧めしません。
他のヒント
Batteries Included を使用すると、次のように記述できます
let nums = List.of_enum (1--10);;
-
演算子は、最初の値から2番目の値への列挙を生成します。 -^
演算子も同様ですが、半開間隔を列挙します( 1-^ 10
は1から9まで列挙します)。
ここに行きます:
let rec range i j = if i > j then [] else i :: (range (i+1) j)
これは末尾再帰ではないことに注意してください。最新のPythonバージョンには遅延範囲もあります。
これはベースOCamlで動作します:
&#65283; List.init 5(fun x-&gt; x + 1);;
-:int list = [1; 2; 3; 4; 5]
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
open Batteries
(標準ライブラリのコミュニティバージョン)を使用する場合、 Listで
( range(1、n + 1)
を実行できます。 .range 1 `To n To
の前の逆引用符に注意してください)。
より一般的な方法(バッテリーも必要)は、 List.init nf
を使用して、(f 0)(f 1)...(f(n-1))を含むリストを返します。
ゲームに少し遅れましたが、ここに私の実装があります:
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つの関数のみが必要で、完全なフレームワークを避けたい場合はこれが良いかもしれません。
ところで、Haskellではむしろ使用したい
enumFromTo 1 n
[1 .. n]
これらは不要です。
take n [1 ..]
take n $ iterate (+1) 1
上からAlex Coventryをフォローしていますが、さらに短くなっています。
let range n = List.init n succ;;
> val range : int -> int list = <fun>
range 3;;
> - : int list = [1; 2; 3]
&quot;ステップ&quot;が必要ない場合パラメータ、この関数を実装する簡単な方法の1つは次のとおりです。
let start start = List.init(abs @@ stop-start)(fun i-&gt; i + start)