私が定義する場合
fun id x = x
それから自然id
にタイプを持っています'a -> 'a
もちろん、は にid 0
評価されますが0
、これは完全に理にかなっています。
これは完全に理にかなっているので、関数でカプセル化できるはずです。
fun applyToZero (f: 'a -> 'a) = f 0
applyToZero
タイプが('a -> 'a) -> int
あり、applyToZero id
評価されることを願って0
しかし、applyToZero
上記のように定義しようとすると、SML/NJ は次のような奇妙なエラー メッセージを表示します。
unexpected exception (bug?) in SML/NJ: Match [nonexhaustive match failure]
raised at: ../compiler/Elaborator/types/unify.sml:84.37
これは、コンパイラ自体のバグのように見えます。奇妙ですが、可能です。
しかし、PolyML も気に入りません (ただし、エラー メッセージはそれほど奇妙ではありません)。
> fun applyToZero (f: 'a -> 'a) = f 0;
poly: : error: Type error in function application.
Function: f : 'a -> 'a
Argument: 0 : int
Reason: Can't unify int to 'a (Cannot unify with explicit type variable)
Found near f 0
以下は機能します:
fun ignoreF (f: 'a -> 'a) = 1
推論されたタイプで('a -> 'a) -> int
。これは、このタイプの高階関数を作成することが不可能ではないことを示しています。
SML が の私の定義を受け入れないのはなぜapplyToZero
ですか? タイプが になるように定義できる回避策はあります('a -> 'a) -> int
か?
動機:この質問のパズルを解こうとする試みでtofun
、タイプの関数と、すべての整数に対して望ましいプロパティを持つint -> 'a -> 'a
別の関数を定義することができました。ただし、私の作業の推定タイプは. SML がそれを受け入れるように型注釈を追加しようとする私の試みはすべて失敗しました。その質問をした人がまだそのパズルに取り組んでいる可能性があるため、 の定義を示したくありませんが、 の定義はまったく同じエラーメッセージを引き起こします。fromfun
fromfun (tofun n) = n
n
fromfun
('int -> 'int) -> 'int)
('a -> 'a) -> int
fromfun
applyToZero