比较Haskell中的函数

时间:2019-05-29 03:38:12

标签: function haskell

我有一个看起来像[Command]的命令列表([forward 15, left 20, right 10])。 我想在每次看到forward 15命令时将[Command]添加到forward 15。我使用了elem==来比较元素是否为forward 15,但是它给了我No instance for (Eq Command) arising错误。 另外,在另一个函数中,只要我看到4个连续的[left 15, forward 15, forward 15, right 15, right 15, forward 15, forward 15, left 15]命令,就想向[Command]添加forward 15。 因此,我的问题是如何比较函数,因为forward是一个函数,我无法使用elem==进行比较。

Command被定义为type,而不是data,因此我不能使用deriving Eq

type Command = Funcs -> (Picture, Funcs)

data Funcs = Funcs {pen :: Bool, angle :: Float, point :: Point, penColor :: Color} deriving (Eq, Show)

forward :: Float -> Command
forward x = ....

2 个答案:

答案 0 :(得分:8)

我建议为命令创建新的数据类型,并为Command语义域添加解释器。例如:

data ReifiedCommand
    = Forward Float
    | Backward Float
    | Left Float
    | Right Float
    deriving (Eq, Ord, Read, Show)

interpret :: ReifiedCommand -> Command
interpret (Forward x) = forward x
interpret (Backward x) = backward x
interpret (Left x) = left x
interpret (Right x) = right x

现在,您可以比较ReifiedCommand的平等性,并进行任何检查以构建合适的[ReifiedCommand],然后立即全部interpret进行比较。 [Command](或更可能是单个Command)。

答案 1 :(得分:0)

您可能在deriving定义中缺少data子句。

Prelude> data Command = Forward Int | Left Int | Right Int deriving (Eq, Show)
Prelude> Forward 15 == Forward 15
True

如果没有派生子句,您将看到

  

没有任何因使用'=='

而引起的(Eq Command)实例

顺便说一句,虽然Forward确实是一个(构造函数)函数,但是您要确保不对函数本身进行==比较(您不能这在Haskell中),而是应用功能的结果。所以你永远无法比较

Forward == Forward

因为Forward的类型为Int->Command(一个函数),但是您可以比较

Forward 15 == Forward 15

只要将类型CommandEq类型类相关联即可。