-->

对于“秀”哈斯克尔暧昧类型的变量?(Haskell ambiguous type variable

2019-09-30 05:13发布

请现在看到这个新的代码,也没有使用“读”,我仍然得到模棱两可的“秀”的错误:

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.

Answer 1:

在子表达式(show Cons3)没有上下文,以确定的类型参数MyType1

Cons3为任何构造MyType1 a ,并呼吁show它限制a以实例Show ,但除此之外,没有什么可以推断。 因此,类型变量是含糊的,因为没有数值约束,它不能被默认的(除非您启用ExtendedDefaultRules )。

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

show (Cons3 `asTypeOf` t)

或 - 例如 -

show (Cons3 :: MyType1 String)

那里。



Answer 2:

回答第一个问题:

你的不确定性确实来自读取功能!

如果您使用LEN和rev的特定类型的版本,它会工作。 例如,您可以取代len(len :: [Int] -> Int)或更换(read val)(read val :: [Int])


回答第二个问题:

Cons3 :: MyType1 a

所以哈斯克尔不知道什么类型a为。 你可以明确指定(这不要紧,你选择什么,如果你只是show荷兰国际集团吧):

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根据上下文,但你创建一个从字面,并显示它马上,所以没有上下文。



Answer 3:

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



文章来源: Haskell ambiguous type variable for “show”?