(灵感来自无法匹配具有约束的多态元组 https://stackoverflow.com/questions/57137421/cannot-match-on-polymorphic-tuples-with-constraints,并基于随后的comment https://stackoverflow.com/questions/57137421/cannot-match-on-polymorphic-tuples-with-constraints#comment100805403_57138105根据我自己的回答。)
考虑以下最小示例:
test :: (Show a, Show b) => (a -> String, b -> String)
test = (show,show)
(resX, resY) = test
这会导致以下错误:
• Ambiguous type variable ‘a0’ arising from a use of ‘test’
prevents the constraint ‘(Show a0)’ from being solved.
Relevant bindings include
resX :: a0 -> String (bound at so.hs:25:2)
Probable fix: use a type annotation to specify what ‘a0’ should be.
These potential instances exist:
instance Show Ordering -- Defined in ‘GHC.Show’
instance Show Integer -- Defined in ‘GHC.Show’
instance Show a => Show (Maybe a) -- Defined in ‘GHC.Show’
...plus 22 others
...plus 17 instances involving out-of-scope types
(use -fprint-potential-instances to see them all)
• In the expression: test
In a pattern binding: (resX, resY) = test
|
25 | (resX, resY) = test
| ^^^^
这是有道理的:模式匹配不会受到限制a
or b
无论如何,所以他们是模棱两可的。但我该如何摆脱这个错误呢?几乎每次尝试通过添加类型签名来解决此问题都会产生另一个错误。例如:
-- attempt 1
test :: (Show a, Show b) => (a -> String, b -> String)
test = (show,show)
resX :: Show a => a -> String
resY :: Show b => b -> String
(resX, resY) = test
-- attempt 2
test :: (Show a, Show b) => (a -> String, b -> String)
test = (show,show)
(resX, resY) = test :: (Show a, Show b) => (a -> String, b -> String)
那么:我怎样才能摆脱歧义错误呢?而为什么上述尝试都失败了呢?