OCamlでリストを操作する
-
10-07-2019 - |
質問
以下のコンテキストでOCamlの深くネストされたリストの操作に問題があります。
class foo (pIn:int)=
object (self)
val p = pIn
val even = if (pIn mod 2) = 0 then true else (false)
method doIt = "doIt"
method isEven = even
method getP = p
end;;
let rec createListOfElements howMany = (
Random.self_init ();
if howMany > 1 then ((new foo (Random.int 10))::(createListOfElements (howMany - 1)))
else ([(new foo (Random.int 10))]) );;
let myList = createListOfElements 5;;
let rec process1 param =
if param <= 10 then
let f = new foo param in (
if f#isEven then (myList <- List.append myList (createListOfElements f#getP));
Printf.printf "%s\n" f#doIt;
process1 (param+1) )
in process1 0;;
エラーは、「バインドされていないインスタンス変数myList」です。このコンテキストで&quot; List.append myList(createListOfElements f#getP)の結果をmyListに割り当てるにはどうすればよいですか?
ありがとう!
編集された関数:
let myList = ref (createListOfElements 5);;
let rec process1 param =
if param <= 10 then
let f = new foo param in (
if f#isEven then (myList <- !myList @ (createListOfElements f#getP));
Printf.printf "%s\n" f#doIt;
process1 (param+1) )
in process1 0;;
解決
永続性を破るには参照を使用する必要があります-関数型プログラミングは永続データを使用するためです。 myListの宣言で ref
キーワードを使用します:
let myList = ref (createListOfElements 5)
リストを間接参照するには、!
を使用します。したがって、問題の行は
if f#isEven then
myList := !myList @ f#getP;
次のように、関数型プログラミングスタイルの精神に基づいてアキュムレータを使用することをお勧めします。
let rec process1 lst = function
| x when x <= 10 ->
let f = new foo x in
if f#isEven then
process1 (lst @ (createListOfElements f#getP)) (param+1)
else
process1 lst (param+1)
| _ -> lst
編集:
コードをコンパイルせず、間違ったシンボルを使用して参照の値を変更していることに気付きませんでした。正しいシンボルは、:=
です。上記の私の変更を参照してください。ただし、参照を避けて、アキュムレータルートに進むことを強くお勧めします。
所属していません StackOverflow