Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 使用函数派生数据类型的实例_Haskell - Fatal编程技术网

Haskell 使用函数派生数据类型的实例

Haskell 使用函数派生数据类型的实例,haskell,Haskell,我正在尝试创建一种数据类型,它表示一个对象的位置,可以“前进”、“停止”、“向前移动”和“向后移动”。我不知道如何为函数前后写'Eq'和'Show'的派生实例 data Moves = GO | STOP | FORWARD { f :: Int -> Int -> Int } | BACKWARD { g :: Int -> Int -> Int } deriving (Eq, Sh

我正在尝试创建一种数据类型,它表示一个对象的位置,可以“前进”、“停止”、“向前移动”和“向后移动”。我不知道如何为函数前后写'Eq'和'Show'的派生实例

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
。我明白了,谢谢您的解释。应要求,我已将此作为答复。