1

この新しく書かれたコードを見てください。「read」は使用されていませんが、あいまいな「show」でエラーが発生します。

data MyType0 a = Tong1 a | Tong2 a  deriving Show
data MyType1 a = Cons1 a | Cons2 a | Cons3 | Cons4 deriving Show
data MyType2 a = MyType2 a deriving Show

fun ((Cons2 s):t:ts) (symseq, MyType2 msg) = (symseq, MyType2 (msg ++ ["You provided wrong symbol: " ++ (show t) ++ " Please provide symbol: " ++ (show Cons3) ]))
--fun ((Cons2 s):t:ts) (symseq, MyType2 msg) = (symseq, MyType2 (msg ++ ["You provided wrong symbol: " ++ (show t) ++ " Please provide symbol: " ]))
fun _ syms                                  = syms

ghci エラー メッセージ:

showerr.hs:6:148:
    Ambiguous type variable `a0' in the constraint:
      (Show a0) arising from a use of `show'
    Probable fix: add a type signature that fixes these type variable(s)
    In the second argument of `(++)', namely `(show Cons3)'
    In the second argument of `(++)', namely
      `" Please provide symbol: " ++ (show Cons3)'
    In the second argument of `(++)', namely
      `(show t) ++ " Please provide symbol: " ++ (show Cons3)'
Failed, modules loaded: none.

コメント部分ではこのエラーが発生しないことに注意してください。なぜこれがエラーなのか説明してください。

元のメッセージは以下に保持されます。

サイトで次のコードを取得しました。「読み取り」関数であいまいな型エラーが発生する可能性があることは知っていますが、ここでは「表示」関数でもエラーが発生します。私はそれが奇妙で理解できないと思います。

コード:

main = do run <- getLine
          val <- getLine
          case run of
              "len" -> print . show . len $ (read val)
              "rev" -> print . show . rev $ (read val)
              _ -> putStr "wrong option"

rev :: [a] -> [a]
rev = foldl (flip (:)) []

len :: [a] -> Int
len = foldl (\ac _ -> ac + 1) 0

ghci にロードすると、エラーが発生します。

ideone_x0cMx.hs:4:46:
    Ambiguous type variable `a0' in the constraint:
      (Read a0) arising from a use of `read'
    Probable fix: add a type signature that fixes these type variable(s)
    In the second argument of `($)', namely `(read val)'
    In the expression: print . show . len $ (read val)
    In a case alternative: "len" -> print . show . len $ (read val)

ideone_x0cMx.hs:5:46:
    Ambiguous type variable `a1' in the constraints:
      (Read a1) arising from a use of `read' at ideone_x0cMx.hs:5:46-49
      (Show a1) arising from a use of `show' at ideone_x0cMx.hs:5:32-35
    Probable fix: add a type signature that fixes these type variable(s)
    In the second argument of `($)', namely `(read val)'
    In the expression: print . show . rev $ (read val)
    In a case alternative: "rev" -> print . show . rev $ (read val)
Failed, modules loaded: none.
4

3 に答える 3

2

部分式(show Cons3)には、 の型パラメータを決定するコンテキストがありませんMyType1

Cons3は任意の のコンストラクタでありMyType1 a、それを呼び出すとのインスタンスにshow制限されますが、それ以上は何も推論できません。したがって、型変数はあいまいであり、数値の制約がないため、デフォルトにすることはできません (有効にしない限り)。aShowExtendedDefaultRules

次のように書くと、型変数を修正できます

show (Cons3 `asTypeOf` t)

または - たとえば -

show (Cons3 :: MyType1 String)

そこの。

于 2012-10-28T15:49:45.550 に答える
2

最初の質問への回答:

あなたのあいまいさはread 関数から来ています!

タイプ固有のバージョンの len と rev を使用すると、機能します。たとえば、次のように置き換えるlen(len :: [Int] -> Int)、次のように置き換えること(read val)ができます。(read val :: [Int])


2 番目の質問への回答:

Cons3 :: MyType1 a

そのため、Haskell は型が何であるかを知りませんashow明示的に指定することもできます (単にing するだけであれば、何を選択してもかまいません):

fun ((Cons2 s):t:ts) (symseq, MyType2 msg) = 
    (symseq, MyType2 (msg ++ ["You provided wrong symbol: " ++ (show t) 
       ++ " Please provide symbol: " ++ show (Cons3 :: MyType Int) ]))

通常はCons3コンテキストから型を推測できますが、リテラルから作成してすぐに表示するため、コンテキストはありません。

于 2012-10-28T14:41:18.193 に答える
0

どのタイプにする必要read valがありますか?あなたのコードはそれがリストであるべきだと言っていますが(revそしてlen両方ともすべてのタイプのリストを受け入れるので)、それが何のリストであるべきかを言っていません。

于 2012-10-28T14:34:47.753 に答える