2017-11-28 19 views
2

私は問題はそれだけでemaulateしようとして標準ML構文

w.sml:21.6-22.82 Error: right-hand-side of clause doesn't agree with function result type [circularity] 
expression: ('Z -> 'Y) -> 'Z -> 'Z 
result type: ('Z -> 'Y) -> 'Z 
in declaration: 
whilestat2 = (fn arg => (fn <pat> => <exp>)) 

uncaught exception Error 
raised at: ../compiler/TopLevel/interact/evalloop.sml:66.19-66.27 
     ../compiler/TopLevel/interact/evalloop.sml:44.55 
     ../compiler/TopLevel/interact/evalloop.sml:292.17-292.20 

私にイムを次のエラーを与えることである標準的なMLに新たなんだと、次のコード

fun whilestat test stmt1 = 
     (fn x => if (test x) then (stmt1 x;whilestat test stmt1) else (x)); 

を書き込もうとし条件が真であれば再帰し、そうでなければその値を返す。

+0

'キャッチされない例外ERROR'はSML/MJコンパイラ自身のためではなく、あなたのコード内のコードのバグを示します(によってトリガされたものとはいえあなたのコードのバグ)。私は過去にそのバグに遭遇しましたが、その後修正されていることは間違いありません。私が使っているバージョン(110.82)では、あなたのコードを実行すると、その二次エラーメッセージは表示されません。 –

答えて

6

問題は返品タイプwhilestatにあります。 thenブランチでは、関数を返しますが、elseブランチでは、任意のデータを返します。私はあなたがthenブランチで再帰するときにすべての引数を渡すのを忘れてしまったと思います。

私はそれをどのように書いていますか(あなたの混乱に寄与したと思うfn x => ...を使用する必要はないことにも注意してください)。

fun whilestat test stmt1 x = 
    if test x 
    then (stmt1 x; whilestat test stmt1 x) 
    else x 

将来、推論を再確認するために、ソースコードの型に明示的に注釈を付けると便利な場合があります。私は以下の???に記入しようとすることで、あなたのバグを見つけました:

fun whilestat (test : 'a -> bool) (stmt1 : 'a -> unit) : ??? = 
    ... 
+0

私はあなたが意味することをよく分かりません--- 'whilestat'は関数である引数(この場合は' test'と 'stmt1')を取るため、高次関数です。 おそらく、あなたは_currying_というコンセプトについて読むのに役立つかもしれません。特に、小さな例として、 'fun f x = fn y => x + y'は' fun f x y = x + y'と等価であると考えてください。 –

+0

リフレクションでは、カレイド関数は、引数の型に関係なく、必ず高次関数であると仮定します。これは、部分的に適用して関数型の値を取得できるためです。それにもかかわらず、あなたは_currying_と_partial application_について読むことが役立つと思います。 –