现在请看这个新编写的代码,没有使用“读取”,但我仍然在模糊的“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.
我在网站上获得了以下代码。我知道模糊类型错误可以用于“读取”功能但是在这里我也得到了“show”功能。我发现它很奇怪而且不明白。
代码:
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.
答案 0 :(得分:2)
回答第一个问题:
你的歧义 来自阅读功能!
如果您使用len和rev的特定于类型的版本,它将起作用。例如,您可以将len
替换为(len :: [Int] -> Int)
或将(read val)
替换为(read val :: [Int])
回答第二个问题:
Cons3 :: MyType1 a
所以Haskell不知道类型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
的类型,但是您可以从文字中创建一个并直接显示它,因此没有上下文。
答案 1 :(得分:2)
在子表达式(show Cons3)
中,没有用于确定MyType1
的类型参数的上下文。
Cons3
是任何MyType1 a
的构造函数,并且在其上调用show
会将a
限制为Show
的实例,但除此之外,什么都不能推断。所以类型变量是不明确的,因为没有数字约束,所以不能默认(除非你启用ExtendedDefaultRules
)。
如果你写
,可以修复类型变量show (Cons3 `asTypeOf` t)
或 - 例如 -
show (Cons3 :: MyType1 String)
那里。
答案 2 :(得分:0)
read val
应该是什么类型的?您的代码说它应该是一个列表(因为rev
和len
都接受所有类型的列表),但没有说它应该是什么类型的列表。