如何为具有不同构造函数Haskell的类型实例化Eq(或任何类)

Onl*_*ies 1 haskell

我对此事有疑问.

如果我有这种类型:

data Person = Person {name :: String, age :: Int} 

data Example = Constructor1 Integer | Constructor2 Person
Run Code Online (Sandbox Code Playgroud)

我想为Example实例化Eq类

instantiate Eq Example where
(==) (Constructor1 e1) (Constructor1 e2) = e1 ==e2
(==) (Constructor2 e1) (Constructor2 e2) = e1 == e2
Run Code Online (Sandbox Code Playgroud)

我们可以假设我已经为Person实例化了Eq类,所以我可以将Person与Person进行比较.

这是实例化具有多个构造函数的类的方法吗?

还有其他疑问.我应该在Constructor1和Constructor2之间添加一个比较.我不这么认为,因为他们可能来自不同的类型.

我在谈论类似这样的东西:

(==) (Constructor1 e1) (Constructor2 e2) == "no idea how to compare Person with Int"
Run Code Online (Sandbox Code Playgroud)

谢谢!

Thi*_*ilo 7

我应该在Constructor1和Constructor2之间添加一个比较吗?

你必须,否则你的实施Eq将是不完整的.

完成所有案例后,只需添加即可

(==) _ _ = False
Run Code Online (Sandbox Code Playgroud)

我不这么认为,因为他们可能来自不同的类型.

但它们属于同一类型,它们都是Example价值观.

所以你的Eq功能需要能够比较它们.

如果你认为在某些条件下拥有a Constructor1 number和a Constructor2 person是有意义的话,你可以编写适当的谓词来做到这一点.但这似乎不寻常,你应该为这种比较而不是使用你自己的类型类Eq.如果使用Eq,请确保它满足反射性,传递性和对称性.


还要注意,对于"无聊"的机制Eq实例,编译器可以自动派生它们(并且它会创建你想要编写的相同的东西):

data Example = Constructor1 Integer | Constructor2 Person
  deriving Eq
Run Code Online (Sandbox Code Playgroud)

你也可以派生出来Show.

https://www.reddit.com/r/haskell/comments/28gxxz/how_does_deriving_eq_work/


Wil*_*sem 5

我应该在Constructor1和之间加一个比较Constructor2.我不这么认为,因为他们可能来自不同的类型.

嗯,这当然取决于你,你可以指定Constructor1 i等于给Constructor2 p定的age p == fromIntegral i,所以这Constructor1基本上保持一个"年龄"并且Constructor2相等于给定该年龄的构造函数具有该年龄,但这取决于认为的两个平等Example的.只要您的函数满足等价关系条件就没有问题.

如果您不希望任何Constructor1对象等于Constructor2,则应添加False在该情况下返回的行:

instance Eq Example where
    (==) (Constructor1 e1) (Constructor1 e2) = e1 == e2
    (==) (Constructor2 e1) (Constructor2 e2) = e1 == e2
    (==) _ _ = False
Run Code Online (Sandbox Code Playgroud)

但是你可以在特定情况下省去麻烦,只需写下:

data Example = Constructor1 Integer | Constructor2 Person deriving Eq
Run Code Online (Sandbox Code Playgroud)

然后Haskell instance Eq自动实现,其中两个Example对象被认为是相等的,因为数据构造函数是相同的,并且所有参数都相等.在所有其他情况下,这两个对象被认为是相等的.