4

Jason Hickey の Introduction to Objective Caml を学んでいます。

let第 3 章を学んだ後、とがどのように機能するかを理解したようですfun。それでも、自分で書くのは面倒funです。


これが私が直面している問題の例です。

Write a function sum that, given two integer bounds n and m and a function f, computes a summation (no for loop allowed). i.e., sum n m f = f(n) + f(n+1) + ... + f(m)


では、この関数 sum を生成することについてどのように考え始めればよいでしょうか?

Java や通常のプログラミング言語では簡単です。

ここでは for ループが許可されていないので、let rec方法で行う必要があるのでしょうか。

このようなもの:

let rec sum n m f = fun i -> ....

iをカーソルにする必要がありますか?

とにかく、考え続けることができません。

OCamlの楽しみを生み出すための道を誰かが指摘できますか?


これが私の最終的な解決策です:

let rec sum n m f = if n <= m then (f n)+(sum n+1 m f) else 0;;

もちろん、それは間違っています。エラーはError: This expression has type 'a -> ('a -> int) -> 'b but an expression was expected of type int

なんで?とは何ですか?

4

3 に答える 3

6

あなたは古典的な構文の間違いをしました:あなたが期待するものの代わりにsum n+1 m fとして解析されます。(sum n) + (1 n f)OCamlでは、関数適用(スペース)は中置演算子よりも優先されます。

タイプエラーは、sum n(合計で使用する)が整数ではないという事実に起因します。もう1つの引数(m)と整数を返す関数が必要です。型推論プロセスのこの時点(エラーが発生したとき)で、OCamlはこれを次のように表します'a -> ('a -> int) -> 'b:未知のものa、関数fromaからintを受け取り、いくつかのものを返しますb

于 2012-12-04T15:23:46.183 に答える
6

これが、ループではなく再帰の観点から考えるのに役立つことを願っています (テール再帰はしばらく省略しましょう)。

したがって、計算する必要がありますf(n) + f(n+1) + ... f(m)この問題を帰納的に考えると役立つかもしれません。つまり、 の計算方法を知っていると仮定するとf(n+1) + ... + f(m)、元の結果を計算するにはどうすればよいでしょうか? まあ、f(n)後者に追加するだけですよね?それはまさにあなたのコードが言わなければならないことです:

let rec sum n m f =
  if n = m then
    f m
  else
    f n + sum (n + 1) m f;; (* here's the inductive step *)

f(n)の結果にどのように追加したかがわかりますf(n+1) + .... + f(m)。したがって、帰納的に考え、問題をより小さな断片に分解し、それらの小さな断片の結果をどのように組み合わせることができるかを考えてください.

私が物事をもっと混乱させなかったことを願っています。

于 2012-12-04T16:29:21.797 に答える
1

'aJavaのジェネリック型のようなものです。例: let test a = 1 そのタイプは次のとおりです。'a -> int この関数は、引数のタイプに関係なく1を返します。

エラーは、ここに括弧を入れる必要があるということです (sum (n+1) m f)

Ocamlはそれを余分な引数と考えていたので、意図したものとは異なるタイプになります。かっこを付けると、正しい数の引数があることを確認できます。コードがたくさんある場合にデバッグするのは微妙な問題です。したがって、同様の状況で括弧を使用すると、時間を大幅に節約できます。:)

于 2012-12-04T15:33:34.720 に答える