2

私はOCamlを始めたばかりですが、OCamlの使い方をよく理解するために、過去2日間ずっと働いていました。私は最近たくさんのことをしていますが、何かが私を前進させるのを妨げています。

OCamlにevalexprを実装しようとしています。あなたが言うだろうこの言語を使うのはとても簡単です:それで私は考えました、そして私が最初にしたことは、通常のintを使って、うまくいきました。しかし今、私は自分のOWN型と自分の関数を使って演算を解こうとしています。もちろん、思ったほど簡単ではありません。

type expr =
  | Number of MyInt.myint
  | Sum of (expr * expr)
  | Sub of (expr * expr)
  | Product of (expr * expr)
  | Divide of (expr * expr)
  | Modulo of (expr * expr)

let rec evalexpr expr = function
  | Number n       -> n
  | Sum (a, b)     -> MyInt.add (evalexpr a) (evalexpr b)
  | Sub (a, b)     -> MyInt.sub (evalexpr a) (evalexpr b)
  | Product (a, b) -> MyInt.mul (evalexpr a) (evalexpr b)
  | Divide (a, b)  -> MyInt.div (evalexpr a) (evalexpr b)
  | Modulo (a, b)  -> MyInt.modulo (evalexpr a) (evalexpr b)

これは私には問題ないようです...しかし、コンパイラは同意しません。「(evalexpra)」がMyInt.myint型であることは明らかだと思います。これは、evalexpr関数が返すことができる唯一の最終的な戻り値であるためです。それでも、コンパイラはその型が「expr->MyInt.myint」であると見なします。 。

関数evalexprを適用せず、関数自体を返すという意味ですか?もしそうなら、なぜそれはそれをするのでしょうか?私はそれを理解することができません。そして、私がここで達成しようとしていることを行うための別の方法を考えることはできません。

4

2 に答える 2

7

関数から削除exprしますevalexpr

let rec evalexpr = function
    ...

そこにあることで、関数が2つのパラメーターを取ることを宣言しています。1つ目は変数にバインドされexpr、2つ目は関数本体で照合されます。次に、再帰的に呼び出そうとするとevalexpr、単一のパラメーターを使用して呼び出し、2番目のパラメーターを期待する関数を生成します。そうすると、当然、関数は関数を操作できないため、エラーが発生します。

于 2011-03-21T22:44:47.530 に答える
2

わかりました、私はそれがこのようになるべきだと思います:

let rec evalexpr = function
  | Number n       -> n
  | Sum (a, b)     -> MyInt.add (evalexpr a) (evalexpr b)
  | Sub (a, b)     -> MyInt.sub (evalexpr a) (evalexpr b)
  | Product (a, b) -> MyInt.mul (evalexpr a) (evalexpr b)
  | Divide (a, b)  -> MyInt.div (evalexpr a) (evalexpr b)
  | Modulo (a, b)  -> MyInt.modulo (evalexpr a) (evalexpr b)

関数ステートメントはすでに引数を取っているので、実際に宣言したのは1つの引数を取り、関数を返す関数でした

于 2011-03-21T22:53:44.073 に答える