17

bazの型宣言が追加されると、このコードは壊れます。

baz (x:y:_) = x == y
baz [_] = baz []
baz [] = False

一般的な説明 (例については、推論された型を宣言できないのはなぜですか?を参照) は、多相再帰が原因であるというものです。

しかし、その説明は、別のポリモーフィックな再帰的な例で効果が消える理由を説明していません:

foo f (x:y:_) = f x y
foo f [_] = foo f []
foo f [] = False

また、GHC が再帰が型宣言なしで単相的であると考える理由も説明していません。

http://www.haskell.org/onlinereport/decls.html#sect4.5.5readsの例の説明は私のケースに適用できますか?baz

つまり、署名を追加すると、単一型の制限が取り除かれ、制限がないと、右辺 [] のあいまいさが現れ、「本質的にあいまいな」タイプのforall a . Eq a => [a]?

4

2 に答える 2

13

の方程式bazは1つのバインディンググループにあり、一般化はグループ全体が入力された後に行われます。型シグネチャがない場合、bazそれはモノタイプを持っていると想定されるため[]、再帰呼び出しのタイプはそれによって与えられます(ghcの-ddump-simpl出力を見てください)。型シグニチャーを使用すると、コンパイラーは関数が多態性であると明示[]的に通知されるため、再帰呼び出しの型が同じであると想定できないため、あいまいになります。

John Lが言ったように、では、モノタイプがある限り、タイプfooは-の出現によって固定されます。(が必要)と同じタイプを指定することで、同じあいまいさを作成できます。fff(==)Rank2Types

{-# LANGUAGE Rank2Types #-}
foo :: Eq b => (forall a. Eq a => a -> a -> Bool) -> [b] -> Bool
foo f (x:y:_) = f x y
foo f[_] = foo f []
foo _ [] = False

それは

Ambiguous type variable `b0' in the constraint:
  (Eq b0) arising from a use of `foo'
Probable fix: add a type signature that fixes these type variable(s)
In the expression: foo f []
In an equation for `foo': foo f [_] = foo f []
于 2011-11-25T15:38:51.260 に答える
11

2番目の例は、多形的に再帰的ではありません。これは、関数fが再帰的定義のLHSとRHSの両方に表示されるためです。foo、のタイプも考慮して(a -> a -> Bool) -> [a] -> Boolください。これにより、リスト要素のタイプがfの引数のタイプと同じになるように修正されます。その結果、GHCは、RHSの空のリストが入力リストと同じタイプでなければならないと判断できます。

GHCは型署名なしでコンパイルでき、単相制限が無効になっているため、このreads例はこのケースには当てはまらないと思います。したがって、GHCの型アルゴリズムには、あいまいさを取り除く他のメカニズムがあると思います。bazbaz

于 2011-11-25T14:59:26.493 に答える