2017-11-10 12 views
2

私はSML(Javaの世界から来ている)と私が理解しているところから比較的新しいです 構造体はJavaクラスと似ています&署名はJavaインタフェースです。getter/setterをsml構造体に関連付けるには

SML構造のすべてが不変です。値を設定できる変数を持つ可能性はありますか?

functor Make(M : sig 
       type data 
       val callback : _ 
      end) = struct 

    val cb = M.callback 

    fun simple nn = 
     cb(nn); 
     return nn 

    fun changeCallback cc = 
     cb = cc 
end 

上記のコードは、changeCallback関数なしでうまくコンパイルされます。変数cbの値を変更して、別のコールバック関数を与える方法はありますか?

答えて

2

構造体は、インスタンス化できない静的メンバーのみを持つ最も類似したJavaクラスです。 Javaの場合と同様に、グローバルな可変状態を持つことは悪い考えです。

は、あなたはJavaクラスのpublic static Callbackメンバーを持つことができます同じように、

val cb : (argtype -> unit) ref = ref M.callback 

宣言で変更可能なグローバルな状態を追加することができます。しかし、これは問題を引き起こす傾向があります。

functor Make(M : sig 
       type data 
       type arg 
       val callback : arg -> unit 
      end) = struct 

    val cb = ref M.callback 

    fun simple nn = ((!cb) nn; nn) 

    fun changeCallback cc = 
     cb := cc 
end 

はまたSML構造のためのnew演算子が存在しないことに注意してください:あなたはまた、!とリファレンスを読んで、それが:=を使用してへの書き込みを、コードビットの残りの部分を調整する必要があります。 Functorを使用して新しい構造を作成することはできますが、それらのすべてをソースレベルで表現する必要があります。たとえば、ループ内に可変数の構造体を作成することはできません。

Javaクラスをエミュレートするには、レコードを使用する必要があります(おそらく… refのメンバーを持つ)。フロリアンの答えを供給する

+0

これでchangeCallback()内に 'state'を設定できますか?しかし、私は実際にintではない関数参照を持っています。その構文は何でしょうか(すでに '_'を試しています)? –

+0

私は '_'構文を認識しません。私はあなたがfunctorの署名の引数で具体的な型を指定する必要があると思います。 –

1

、SMLはval foo = ref 0foo mutableなint型になり、可変変数、!fooは間接参照値(実際のint型)であるを持っている、foo := 2は、その値を変更し、fun incr r = (r := !r + 1 ; !r)は1で、その可変引数をインクリメント機能です更新された値を返します。これは、モジュールシステム(構造、署名、ファンクタ)を使用せずに行われます。 ;は、命令型言語で見られるように、SMLのバイナリ演算子を "文分離記号"よりも考える方が良いことに注意してください。

SMLはOcamlのようなクラスベースのオブジェクト指向プログラミングをサポートしておらず、率直に言ってモジュールシステムでこれをシミュレートするのは残念です。 Ocaml's object-oriented programmingを調べるとよいでしょう。

クラスベースの考え方がある特定のタスクを達成しようとしている場合は、オブジェクト指向ではないと考えて、「SMLでXをモデル化するにはどうすればよいですか?指向。

関連する問題