对于以下代码:
module Main where
data EitherOr a b = Hello a | Goodbye b deriving Show
instance (Eq a, Eq b) => Eq (EitherOr a b) where
(==) (Hello x) (Hello x') = x == x'
(==) (Goodbye x) (Goodbye x') = x == x'
(==) _ _ = False
main :: IO ()
main = do
print (Hello 2 == Hello 2)
-- print (Hello 3 == Hello 2)
-- print (Goodbye 3 == Goodbye 3)
-- print (Goodbye 4 == Goodbye 3)
-- print (Hello 3 == Goodbye 3)
在runhaskell下执行,即在ghc下执行,得到以下错误:
⢠Ambiguous type variable âb0â arising from a use of â==â
prevents the constraint â(Eq b0)â from being solved.
Probable fix: use a type annotation to specify what âb0â should be.
These potential instances exist:
instance Eq Ordering -- Defined in âGHC.Classesâ
instance Eq Integer
-- Defined in âinteger-gmp-1.0.2.0:GHC.Integer.Typeâ
instance (Eq a, Eq b) => Eq (EitherOr a b)
-- Defined at /tmp/runghcXXXX61964-0.hs:5:10. <-- This is because I am using org-mode source blocks
...plus 23 others
...plus 11 instances involving out-of-scope types
(use -fprint-potential-instances to see them all)
⢠In the first argument of âprintâ, namely â(Hello 2 == Hello 2)â
In a stmt of a 'do' block: print (Hello 2 == Hello 2)
In the expression: do print (Hello 2 == Hello 2)
|
12 | print (Hello 2 == Hello 2)
| ^^^^^^^^^^^^^^^^^^
我想我可以给编译器一个类型提示
print ((Hello (2 :: Int)) == (Hello (2 :: Int)))
或者类似的,但这似乎还不够。我看到a和b是多态的,但我认为在main中使用==可能足以帮助编译器推断类型。
接下来,我在ghci中加载了数据类型和类型类实例,并对这些类型进行了一些探索,发现
λ> :t Hello (2 :: Int)
Hello (2 :: Int) :: EitherOr Int b
如预期。再次在ghci中,我做了更多的探索,并看到正在使用默认类型
>:t(你好2==你好2)
<interactive>:1:2: warning: [-Wtype-defaults]
⢠Defaulting the following constraints to type âIntegerâ
(Eq a0) arising from a use of â==â at <interactive>:1:2-19
(Num a0) arising from the literal â2â at <interactive>:1:8
⢠In the expression: (Hello 2 == Hello 2)
<interactive>:1:2: warning: [-Wtype-defaults]
⢠Defaulting the following constraint to type â()â
Eq b0 arising from a use of â==â
⢠In the expression: (Hello 2 == Hello 2)
(Hello 2 == Hello 2) :: Bool
当然,这是我想要的。
然后我实际在ghci中执行代码,得到正确的答案
λ> Hello 2 == Hello 2
<interactive>:27:1: warning: [-Wtype-defaults]
⢠Defaulting the following constraints to type âIntegerâ
(Eq a0) arising from a use of â==â at <interactive>:27:1-18
(Num a0) arising from the literal â2â at <interactive>:27:7
⢠In the expression: Hello 2 == Hello 2
In an equation for âitâ: it = Hello 2 == Hello 2
<interactive>:27:1: warning: [-Wtype-defaults]
⢠Defaulting the following constraint to type â()â
Eq b0 arising from a use of â==â
⢠In the expression: Hello 2 == Hello 2
In an equation for âitâ: it = Hello 2 == Hello 2
<interactive>:27:1: warning: [-Wtype-defaults]
⢠Defaulting the following constraints to type âIntegerâ
(Eq a0) arising from a use of â==â at <interactive>:27:1-18
(Num a0) arising from the literal â2â at <interactive>:27:7
⢠In the expression: Hello 2 == Hello 2
In an equation for âitâ: it = Hello 2 == Hello 2
<interactive>:27:1: warning: [-Wtype-defaults]
⢠Defaulting the following constraint to type â()â
Eq b0 arising from a use of â==â
⢠In the expression: Hello 2 == Hello 2
In an equation for âitâ: it = Hello 2 == Hello 2
True
但是在runhaskell下执行的相同代码,即在ghc编译下,由于我首先给出的错误而失败。我需要在这里学到什么?