これは本当に簡単です。
∀x. x ⊢ :t isList2
isList2 :: a -> Bool
これは(統一を経て、でもそれはできるけれども)[a]
インスタンスと一致していないが、それはすぐにa
インスタンスと一致しません:のはisList2
の種類が何であるかをGHCiのを聞いてみよう。したがって、GHCはa
インスタンスを選択し、そうisList2
戻るFalse
。
この動作は、正確に何IncoherentInstances
手段です。実際には、これはむしろ素晴らしいデモンストレーションです。あなたは、単にIncoherentInstances
を無効にした場合
は陽気に、我々は全く逆の効果を取得し、GHCiのは、今、この言葉:
∀x. x ⊢ :t isList2
isList2 :: [Integer] -> Bool
isList2
は、関数構文を使用して定義されていない結合のトップレベルであるためですしたがって恐ろしい一形態制限に従う。したがって、実際に使用されるインスタンスに特化します。
NoMonomorphismRestriction
を追加するだけでなく、IncoherentInstances
を無効にすることを、我々は代わりにこれを取得:
∀x. x ⊢ :t isList2
isList2 :: IsList a => a -> Bool
∀x. x ⊢ isList2 'a'
False
∀x. x ⊢ isList2 "a"
True
∀x. x ⊢ isList2 undefined
<interactive>:19:1:
Overlapping instances for IsList a0 arising from a use of `isList2'
選択肢があいまいな場合は、使用や苦情に基づいて選ばれたインスタンスと予想重複行動であり、これは。
質問の編集に関して、私はタイプ注釈なしで希望の結果が可能であるとは思わない。
最初のオプションは、isList2
にタイプシグニチャを指定することです。これにより、IncoherentInstances
がインスタンスをあまりにも早く選択できなくなります。
isList2 :: (IsList a) => a -> Bool
isList2 = isList
はおそらく、引数に適用されることなく、どこか他のisList
は(たとえ間接的に)記載されて同じことを行う必要があります。
2番目のオプションは、数値リテラルを明確にし、IncoherentInstances
を無効にすることです。
この場合
main =
print (isList (42 :: Integer)) >>
print (isList2 (42 :: Integer)) >>
print (isList [42]) >>
print (isList2 [42])
、そうOverlappingInstances
はそのことをし、最も特定のインスタンスを選択するのに十分な情報があります。
あなたのプログラムはインコヒーレントなので、本当に、あなたは何を期待しましたか? –
私は出力が 'True True'ではなくTrue Trueであることを期待しました。なぜあなたは出力が真の偽であると思いますか?インコヒーレントなプログラムがTrue Trueを返さないのはなぜですか?あなたは出力の理由がないと言っていますが、その結果は未定義です。本当にTrue Trueを返すことがありますか? – Clinton
可能性のある複製の[IncoherentInstancesはどのように動作しますか?](http://stackoverflow.com/questions/8371499/how-does-incoherentinstances-work) –