【问题标题】:Haskell ambiguous type variable for "show"?“show”的Haskell模棱两可的类型变量?
【发布时间】:2012-10-18 01:20:45
【问题描述】:

现在请看这段新写的代码,没有使用“读取”,但我仍然在模棱两可的“显示”上出错:

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.

【问题讨论】:

    标签: haskell types ambiguous


    【解决方案1】:

    在子表达式(show Cons3)中,没有上下文来判断MyType1的类型参数。

    Cons3 是任何MyType1 a 的构造函数,在其上调用show 会将a 限制为Show 的实例,但除此之外,无法推断任何内容。所以类型变量是不明确的,而且由于没有数值约束,所以不能默认(除非你启用ExtendedDefaultRules)。

    如果你写,类型变量可以固定

    show (Cons3 `asTypeOf` t)
    

    或者——例如——

    show (Cons3 :: MyType1 String)
    

    那里。

    【讨论】:

      【解决方案2】:

      第一个问题的答案:

      您的歧义确实来自读取功能!

      如果您使用特定类型的 len 和 rev 版本,它会起作用。例如,您可以将len 替换为(len :: [Int] -&gt; Int) 或将(read val) 替换为(read val :: [Int])


      第二个问题的答案:

      Cons3 :: MyType1 a
      

      所以 Haskell 不知道 a 是什么类型。您可以明确指定(如果您只是 showing 它,您选择什么都没关系):

      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 的类型,但是您从文字中创建一个并立即显示它,因此没有上下文。

      【讨论】:

      • 请看新编辑的代码。我删除了“读取”功能,但仍然出现模棱两可的“显示”错误。
      【解决方案3】:

      read val 应该是什么类型?您的代码说它应该是一个列表(因为 revlen 都接受所有类型的列表),但没有说明它应该是一个列表。

      【讨论】:

        猜你喜欢
        • 2012-12-18
        • 2018-10-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-09-30
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多