没有因使用“==”而产生的(Eq a)实例
No instance for (Eq a) arising from a use of `=='
在下面的Haskell代码中:
import Data.List
import Data.Char
data EXP a = Empty | Symbol a
deriving (Show, Eq, Ord)
test :: (Ord a) => EXP a -> [[a]]
test Empty = []
test (Symbol x) = [[x]]
value = (test Empty) == []
我收到以下错误:
problem.hs:12:10:
No instance for (Ord a0) arising from a use of `test'
The type variable `a0' is ambiguous
Note: there are several potential instances:
instance Ord a => Ord (EXP a) -- Defined at problem.hs:5:32
instance Integral a => Ord (GHC.Real.Ratio a)
-- Defined in `GHC.Real'
instance Ord GeneralCategory -- Defined in `Data.Char'
...plus 26 others
In the first argument of `(==)', namely `(test Empty)'
In the expression: (test Empty) == []
In an equation for `value': value = (test Empty) == []
problem.hs:12:22:
No instance for (Eq a0) arising from a use of `=='
The type variable `a0' is ambiguous
Note: there are several potential instances:
instance Eq a => Eq (EXP a) -- Defined at problem.hs:5:28
instance Eq a => Eq (GHC.Real.Ratio a) -- Defined in `GHC.Real'
instance Eq GeneralCategory -- Defined in `Data.Char'
...plus 26 others
In the expression: (test Empty) == []
In an equation for `value': value = (test Empty) == []
Failed, modules loaded: none.
但是如果我删除最后一行,那么代码是:
import Data.List
import Data.Char
data EXP a = Empty | Symbol a
deriving (Show, Eq, Ord)
test :: (Ord a) => EXP a -> [[a]]
test Empty = []
test (Symbol x) = [[x]]
我可以在交互式提示中执行以下操作,不会出错:
Prelude> :l problem.hs
[1 of 1] Compiling Main ( problem.hs, interpreted )
Ok, modules loaded: Main.
*Main> test Empty == []
True
*Main>
为什么当 == 检查在源文件中时出现错误,但在交互式提示中却没有?
只需用类型明确注释它:
value = test Empty == ([] :: [[Int]])
[]
的类型可以是任何类型:[Int]
或 [Float]
或 [[Int]]
。编译器无法弄清楚,因为即使 Exp
也是多态的。如果你的函数是这样的,你就不必显式注释:
test :: EXP Int -> [[Int]]
test Empty = []
test (Symbol x) = [[x]]
value = test Empty == []
或者即使您准备好像这样给它提示:
value :: [[Int]]
value = (test Empty)
value2 = value == []
也就是说,不是使用 Int
,而是使用 ()
进行注释,就像 @bheklir 所做的那样。这是标记类型以消除编译器歧义的更好方法。
你需要value
编译的是本地类型签名
value = (test Empty :: [[()]]) == []
或者更好的是,使用 null
:
value = null $ test Empty
这是因为test
的类型是
test :: EXP a -> [[a]]
而 value
的类型就是 Bool
。编译器无法准确猜测 value
内部使用的 Eq
实例,无法从上下文中推断出来。通常,无论何时看到 == []
,都应将其替换为 null
函数,因为这样可以避免 Eq
约束。
它在 GHCi 中有效,因为当您输入 (test Empty) == []
时,GHCi 的扩展默认规则将自动选择 ()
作为不明确的 a
类型。
在下面的Haskell代码中:
import Data.List
import Data.Char
data EXP a = Empty | Symbol a
deriving (Show, Eq, Ord)
test :: (Ord a) => EXP a -> [[a]]
test Empty = []
test (Symbol x) = [[x]]
value = (test Empty) == []
我收到以下错误:
problem.hs:12:10:
No instance for (Ord a0) arising from a use of `test'
The type variable `a0' is ambiguous
Note: there are several potential instances:
instance Ord a => Ord (EXP a) -- Defined at problem.hs:5:32
instance Integral a => Ord (GHC.Real.Ratio a)
-- Defined in `GHC.Real'
instance Ord GeneralCategory -- Defined in `Data.Char'
...plus 26 others
In the first argument of `(==)', namely `(test Empty)'
In the expression: (test Empty) == []
In an equation for `value': value = (test Empty) == []
problem.hs:12:22:
No instance for (Eq a0) arising from a use of `=='
The type variable `a0' is ambiguous
Note: there are several potential instances:
instance Eq a => Eq (EXP a) -- Defined at problem.hs:5:28
instance Eq a => Eq (GHC.Real.Ratio a) -- Defined in `GHC.Real'
instance Eq GeneralCategory -- Defined in `Data.Char'
...plus 26 others
In the expression: (test Empty) == []
In an equation for `value': value = (test Empty) == []
Failed, modules loaded: none.
但是如果我删除最后一行,那么代码是:
import Data.List
import Data.Char
data EXP a = Empty | Symbol a
deriving (Show, Eq, Ord)
test :: (Ord a) => EXP a -> [[a]]
test Empty = []
test (Symbol x) = [[x]]
我可以在交互式提示中执行以下操作,不会出错:
Prelude> :l problem.hs
[1 of 1] Compiling Main ( problem.hs, interpreted )
Ok, modules loaded: Main.
*Main> test Empty == []
True
*Main>
为什么当 == 检查在源文件中时出现错误,但在交互式提示中却没有?
只需用类型明确注释它:
value = test Empty == ([] :: [[Int]])
[]
的类型可以是任何类型:[Int]
或 [Float]
或 [[Int]]
。编译器无法弄清楚,因为即使 Exp
也是多态的。如果你的函数是这样的,你就不必显式注释:
test :: EXP Int -> [[Int]]
test Empty = []
test (Symbol x) = [[x]]
value = test Empty == []
或者即使您准备好像这样给它提示:
value :: [[Int]]
value = (test Empty)
value2 = value == []
也就是说,不是使用 Int
,而是使用 ()
进行注释,就像 @bheklir 所做的那样。这是标记类型以消除编译器歧义的更好方法。
你需要value
编译的是本地类型签名
value = (test Empty :: [[()]]) == []
或者更好的是,使用 null
:
value = null $ test Empty
这是因为test
的类型是
test :: EXP a -> [[a]]
而 value
的类型就是 Bool
。编译器无法准确猜测 value
内部使用的 Eq
实例,无法从上下文中推断出来。通常,无论何时看到 == []
,都应将其替换为 null
函数,因为这样可以避免 Eq
约束。
它在 GHCi 中有效,因为当您输入 (test Empty) == []
时,GHCi 的扩展默认规则将自动选择 ()
作为不明确的 a
类型。