1

次のコードを検討してください。

fun g(a) =
let     fun h(b)=g(a) 
in  h end; 

SMLで実行すると、次のようになります。

- fun g(a) =
= let   fun h(b)=g(a)
= in    h end;
stdIn:55.5-57.10 Error: right-hand-side of clause doesn't agree with function re
sult type [circularity]
  expression:  'Z -> 'Y
  result type:  'Y
  in declaration:
    g = (fn a => let val <binding> in h end)

ここで問題を理解することはできません:g(a)return h、しかし宣言に特定の戻り値が表示されfun g(a)ない(つまり、のようなものは何も ありませんfun g(a):int)、なぜエラーですか?

ありがとう

4

2 に答える 2

3

gパラメータが1つあるため、タイプはです'X -> 'Y

h(b) = g(a) とは同じ結果タイプである必要がhあり、タイプは。であることを意味します。g'Y
h'Z -> 'Y

したがって、g(x)タイプのxの場合、タイプは。'Xでなければなりません'Y
ただし、の戻り値g(x)h、で、タイプは'Z -> 'Yです。
これは'Y、と同じタイプでなければならないことを意味しますが'Z -> 'Y、これは不可能です。

SMLが言うように、'Z -> 'Y(のタイプ)は(のタイプh)と一致しません。'Yg(a)

手作業で解決しようとすると、

g 1 

h次のような関数になります

h 3

の値です

g 1

これは次のような関数hです...

など、無期限に。

于 2013-02-21T22:07:47.630 に答える
1

ML型推論システムは、最初に関数gを'Zを取り、'Yを返す式として識別しました。しかし、gの結果タイプは'Yであり、これは以前のバインディングhの結果タイプでもあることがわかります。タイプZ->Z->Yのバインディングが期待できます。ただし、関数クロージャにはそれ自体が環境があります。つまり、gをこのようにバインドするようなものです。

fun g a= g

クロージャーにそれ自体も同じ環境がある場合、ML型推論は型を推測できません。

これらの関数は次のように宣言できます。

fun g(a) =
    let     
    fun h(b)=g(a) 
    in  
    h(a)
    end; 

のような

fun g a = g a

今回、あなたのクロージャーはそれ自体の本体を持っています。しかし、それは意味がありません...循環エラーが発生する理由のほんの一例です。

于 2013-02-21T22:09:23.197 に答える