2

以下のコンテキストで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」です。このコンテキストで「List.appendmyList(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;;
4

1 に答える 1

1

関数型プログラミングは永続的なデータを使用するため、永続性を破るには参照を使用する必要があります。refmyList の宣言でキーワードを使用します。

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

編集:

コードをコンパイルしなかったため、参照の値を変更するために間違ったシンボルを使用していることに気付きませんでした。正しい記号は、:=です。上記の変更を参照してください。ただし、参照を避けて、アキュムレータ ルートを使用することを強くお勧めします。

于 2009-03-11T15:29:16.390 に答える