1

以下は、私がやろうとしていることの簡単な例です...

test :: Bounded a => Maybe a -> a
test (Just x) = x
test Nothing  = (maxBound :: a)

maxBound関数は多態的です - 型クラスのメソッドの 1 つですBounded。そのため、使用するときは、必要なバージョンを指定する必要がありますBoundedこの単純化された例では、その型はコンテキストから推測できますが、実際の問題では推測できません。実際の問題では明示的な型が必要ですが、ここではそうではありません。

私の関数もポリモーフィックです。具体的な型を直接指定することはできません。型変数のみを指定します。適切な型変数はaBounded a制約を指定した です。

これをコンパイルすると、次のエラーが発生します...

temp.hs:4:18:
    Could not deduce (Bounded a1) arising from a use of `maxBound'
    from the context (Bounded a)
      bound by the type signature for test :: Bounded a => Maybe a -> a
      at temp.hs:2:9-33
    Possible fix:
      add (Bounded a1) to the context of
        an expression type signature: a1
        or the type signature for test :: Bounded a => Maybe a -> a
    In the expression: (maxBound :: a)
    In an equation for `test': test Nothing = (maxBound :: a)

私が知る限り、これはainが意図したもの (関数のシグネチャの型変数) とはmaxBound :: a別のものと見なされたことを意味します。は、GHC が別々と見なす 2 つの変数のあいまいさを解消するために考案した新しい名前です。GHC は、inがここで任意の型を使用できることを示していると見なし (!)、したがって、「任意の型」では十分な制限がないという理由で不平を言います。aa1aamaxBound :: a

これは、(私が思うに) 最新の Haskell Platform で提供されている GHC バージョン 7.6.3 を使用しています。

以前にも同様の問題がありましたが、常に他の問題が混在していたため、他の問題を修正すると問題はなくなりました。他の問題が原因であるとして却下し、忘れました。ここではそのような贅沢はありません - 上記の最小限の例は実際の問題ではありませんが、まったく同じ問題の解決策に依存しています。

では、なぜ GHC は in を関数全体の型変数から独立したものとして扱っているのaでしょうかmaxBound :: a? aそして、これを修正して正しいバージョンの を選択するにはどうすればよいmaxBoundですか?

4

1 に答える 1

3

Main problem is in fact, that GHC tried to see function as

test :: forall a. Bounded a => Maybe a -> a
test (Just x) = x
test Nothing  = (maxBound :: forall a. a)

You need ScopedTypeVariables extension and rewrite function to:

{-# LANGUAGE ScopedTypeVariables #-}

test :: forall a. Bounded a => Maybe a -> a
test (Just x) = x
test Nothing  = (maxBound :: a)

Now we see, that inner a is depend on outer a

UPDATE

If you already wrote the signatiure, you don't need any extension.

Next function works fine!

test :: Bounded a => Maybe a -> a
test (Just x) = x
test Nothing  = maxBound
于 2013-11-10T17:19:44.220 に答える