Haskell 使用函数派生数据类型的实例
我正在尝试创建一种数据类型,它表示一个对象的位置,可以“前进”、“停止”、“向前移动”和“向后移动”。我不知道如何为函数前后写'Eq'和'Show'的派生实例Haskell 使用函数派生数据类型的实例,haskell,Haskell,我正在尝试创建一种数据类型,它表示一个对象的位置,可以“前进”、“停止”、“向前移动”和“向后移动”。我不知道如何为函数前后写'Eq'和'Show'的派生实例 data Moves = GO | STOP | FORWARD { f :: Int -> Int -> Int } | BACKWARD { g :: Int -> Int -> Int } deriving (Eq, Sh
data Moves = GO
| STOP
| FORWARD { f :: Int -> Int -> Int }
| BACKWARD { g :: Int -> Int -> Int }
deriving (Eq, Show)
instance (Eq Moves) where
FORWARD a == FORWARD b = True
FORWARD a == BACKWARD b = True
BACKWARD a == BACKWARD b = True
BACKWARD a == FORWARD b = True
_ == _ = False
这个实例的逻辑目前并不重要,我只是不知道如何编译它。感谢当您通过派生子句自动派生各种标准TypeClass时,这依赖于数据结构中已有这些类实例的各个字段或分支。由于函数没有
Eq
或Show
的默认实例(这是完全合理的,没有明显的标准方法来确定两个任意函数是否相等*,或者将它们打印为字符串),并且您的数据类型包括两个值为函数的字段,Haskell不可能派生Eq
和Show
实例,这就是编译错误的原因
解决方案是简单地删除派生(Eq,Show)
部分-如果要定义自己的自定义实例,则不需要这个部分。(放置派生
子句的唯一原因是,如果您需要一个实例,并且对“标准”的实例感到满意,这在很多时候都是可以的。不过,在这里,您似乎希望用非标准逻辑实现您自己的实例。如果您的用例需要,这很好。)
*实际上,在数学中,函数相等的含义是很清楚的,函数是由它们的图形定义的,这意味着两个函数相等时,它们必须为每个可能的输入值提供相同的输出。在Haskell编程中,这在理论上仍然很重要(因为不同类型类的“定律”要求不同的函数相等),但通常不可能以任何合理的方式实现,尤其是因为有些函数可以永远运行而不给出结果,因此,实际上,计算函数的等式通常比求解 @RobinZigmond我不太确定应该如何编写它的语法,但是我无法编译实例,因为目前我正在尝试使所有内容都计算为
True
,而不管输入是什么,编译错误是什么?尝试从派生
中删除Eq
,因为这是您自己实现的。这将导致更好的错误。您的Eq
实例很好,是deriving
子句中的Eq
导致了错误。不幸的是,Show
也有同样的问题,没有合理的方法以字符串的形式显示任意函数,因此Haskell Prelude不会尝试为函数实现Show
。我明白了,谢谢您的解释。应要求,我已将此作为答复。