Class Haskell中出现不明确的类
使用Class Haskell中出现不明确的类,class,haskell,ambiguous,Class,Haskell,Ambiguous,使用树并定义一个新的“Eq”我得到了一个”不明确的类出现“Eq”***可以引用:Hugs.Prelude.Eq Main.Eq. 我知道我正在尝试为prelude的现有Eq类添加一个新定义,但我不想使用import prelude hiding(Eq),因为我的新等式使用“==”作为数字类型。操作符被称为“=+”,因为它不是一个真正的等式(我认为已经通过派生“加载”了),而是一个结构等式 data Tree = Nil | Node Int Tree Tree deriving (Eq, Ord
树
并定义一个新的“Eq
”我得到了一个”不明确的类出现“Eq”***可以引用:Hugs.Prelude.Eq Main.Eq.
我知道我正在尝试为prelude的现有Eq类添加一个新定义,但我不想使用import prelude hiding(Eq),因为我的新等式使用“==”作为数字类型。操作符被称为“=+”,因为它不是一个真正的等式(我认为已经通过派生“加载”了),而是一个结构等式
data Tree = Nil | Node Int Tree Tree deriving (Eq, Ord, Show)
instance Eq Tree where
Nil =+ Nil = true
(Node a tl1 tr1) =+ (Node b tl2 tr2) = (a==b) && (tl1==tl2) && (tl1==tl2)
如果有任何建议,我将不胜感激。只需使用完全限定的类名:
module Main where
data Tree = Nil | Node Int Tree Tree deriving (Prelude.Eq, Ord, Show)
class Eq a where
(=+) :: a -> a -> Bool
instance Main.Eq Tree where
Nil =+ Nil = True
(Node a tl1 tr1) =+ (Node b tl2 tr2) = (a==b) && (tl1==tl2) && (tl1==tl2)
但不要那样做
首先,你不应该制造这样的歧义。例如,如果您的
Eq
只是一个结构类,则应改为调用StructEq
。只需使用完全限定的类名:
module Main where
data Tree = Nil | Node Int Tree Tree deriving (Prelude.Eq, Ord, Show)
class Eq a where
(=+) :: a -> a -> Bool
instance Main.Eq Tree where
Nil =+ Nil = True
(Node a tl1 tr1) =+ (Node b tl2 tr2) = (a==b) && (tl1==tl2) && (tl1==tl2)
但不要那样做
首先,你不应该制造这样的歧义。例如,你的
Eq
应该被称为StructEq
,如果它“只是一个结构类”。如果你想让一个新类与一个预定义类共存,你显然应该给它一个适当的可区分名称,例如
class PseudoEq x where
(=+) :: x -> x -> Bool
instance PseudoEq Tree where
Nil =+ Nil = true
Node a tl1 tr1 =+ Node b tl2 tr2
= a==b && tl1==tl2 && tl1==tl2
简单地用Main.Eq
限定实例也可以做同样的事情,但是如果类“不是真正的相等”,那么调用类Eq
会让人感到困惑
(虽然
==
也不需要适当的相等;对于许多类型,这只意味着“在用户可以观察到的所有方面都相等”。如果您希望一个新类与预定义类共存,显然应该给它一个适当的可区分名称,例如
class PseudoEq x where
(=+) :: x -> x -> Bool
instance PseudoEq Tree where
Nil =+ Nil = true
Node a tl1 tr1 =+ Node b tl2 tr2
= a==b && tl1==tl2 && tl1==tl2
简单地用Main.Eq
限定实例也可以做同样的事情,但是如果类“不是真正的相等”,那么调用类Eq
会让人感到困惑
(虽然
==
也不需要是一个适当的等式;对于许多类型,这只意味着“在用户可以观察到的所有方面都相等”。如果要编写自定义等式,为什么要导出Eq
?只需从派生子句中删除Eq
,这一切都应该有效。如果要编写自定义的Eq,为什么要派生Eq
?只要从派生子句中删除Eq
,就可以了。您确定需要这个吗?为什么不能简单地使用派生的Eq
实例,它基本上等同于您的自定义实例(除了缺少的情况Nil=+Node…
,如果您不定义它们,它将使程序崩溃)=
不是Java中的“指针标识”,如果您这样认为的话。您确定需要这个吗?为什么不能简单地使用派生的Eq
实例,它基本上等同于您的自定义实例(除了缺少的情况Nil=+Node…
,如果您不定义它们,它将使程序崩溃)<代码>=不是Java中的“指针标识”,如果你这么认为的话。好吧,根据你的提示,我找到了一个解决方案,可以对树的结构进行真正的比较:[无法以可读的方式发布代码],其中包括Nil=+Nil=True
,Nil=+(Node a tl tr)=False
,(Node a tl tr)=+Nil=False
,(节点a tl1 tr1)=+(节点b tl2 tr2)=(tl1=+tl2)和&(tr1=+tr2)
我意识到我在第一次尝试中犯了一些错误。除非我的教科书上说应该有一种使用Eq实例的方法,这意味着需要Zeta的解。我不会把它写下来;o) 如果教科书上说应该有一个Eq
的实例,它要么意味着派生的实例,要么是前奏曲.Eq
的自定义实例;但几乎可以肯定的是,没有一个新的类也被命名为Eq
。“重载类名”只是在以某种微妙的方式改变整个标准类层次结构的大型项目中完成的,比如。。。它使用自己的、大大缩短的名称,如C
作为环(大致相当于Num
数字)。好的,根据您的提示,我找到了一个解决方案,可以对树的结构进行真正的比较:[无法以可读的方式发布代码],其中包括Nil=+Nil=True
,Nil=+(节点a tl tr)=False
,(节点a tl tr)=+Nil=False
,(节点a tl1 tr1)=+(节点b tl2 tr2)=(tl1=+tl2)&&&(tr1=+tr2)
我意识到我在第一次尝试中犯了一些错误。除非我的教科书上说应该有一种使用Eq实例的方法,这意味着需要Zeta的解。我不会把它写下来;o) 如果教科书上说应该有一个Eq
的实例,它要么意味着派生的实例,要么是前奏曲.Eq
的自定义实例;但几乎可以肯定的是,没有一个新的类也被命名为Eq
。“重载类名”只是在以某种微妙的方式改变整个标准类层次结构的大型项目中完成的,比如。。。它使用自己的名字,比如C
来表示一个环(大致相当于Num
numbers)。因为我不想实现真正的相等,而是一个结构上的相等。我在上面贴了一个工作代码。哦,我明白了。我没有注意到派生实例实际上被使用。。。看起来你只是在派生一个实例,然后试图编写另一个实例,因为我不想实现真正的等式,而是一个结构化的等式。我在上面贴了一个工作代码。哦,我明白了。我没有注意到派生实例实际上被使用。。。看起来您只是在派生一个实例,然后尝试编写另一个实例。