从方程式中导出实例时,Haskell"模式中的解析错误"

Anj*_*ina 0 haskell parse-error

我正在学习Haskell的帮助下"为了大好的学习你的Haskell!" 我目前正在尝试了解类型类和实例.LYAH提供了一个示例,其中调用的类型TrafficLight定义如下:

data TrafficLight = Red | Yellow | Green
Run Code Online (Sandbox Code Playgroud)

现在TrafficLight应该是Eq显示以下行为的实例:

instance Eq TrafficLight where
    Red == Red = True
    Green == Green = True
    Yellow == Yellow = True
    _ == _ = False
Run Code Online (Sandbox Code Playgroud)

为了理解它是如何工作的,我写我叫自己的文件Shop.hs,我试图重写的行为Eq对我ItemSlot.

module Shop where

type Number = Int

data Item =
          BellPepper
        | Cabbage
        | Carrot
        | Lettuce
        | Onion
        | Potato
        | Tomato
        deriving (Show, Read, Eq)

data ItemSlot = ItemSlot {
        item :: Item,
        number :: Number
        } deriving (Show)

instance Eq ItemSlot where
        ((item a) == (item a)) = True -- line that contains the error
        _ == _ = False
Run Code Online (Sandbox Code Playgroud)

但是,如果我在GHCi中加载文件,我会收到以下错误:

Prelude> :l Shop.hs 
[1 of 1] Compiling Shop             ( Shop.hs, interpreted )

Shop.hs:21:11: Parse error in pattern: item
Failed, modules loaded: none.
Run Code Online (Sandbox Code Playgroud)

(我必须承认,我对这里正确的语法是什么感到困惑 - 是它item a还是只是item?只item使用相同的错误,使用更多的括号 - 就像在SO上的另一个问题中的答案一样 - 不会似乎也有帮助.)

我的猜测是我不能使用所使用的item记录语法提供的功能ItemSlot,但是我不知道如何解决这个问题.

Dan*_*ner 5

模式通常以构造函数开头.该ItemSlot类型的构造函数是ItemSlot,所以你会使用它:

instance Eq ItemSlot where
    ItemSlot item a == ItemSlot item' a' = -- use item, item', a, and a'
Run Code Online (Sandbox Code Playgroud)

或者,因为您已经定义ItemSlot为记录,所以有模式的所谓记录语法.您可以按名称而不是位置绑定变量:

instance Eq ItemSlot where
    ItemSlot { item = foo, number = a } == ItemSlot { item = foo', number = a' }
        = -- use foo, foo', a, and a'
Run Code Online (Sandbox Code Playgroud)

如果您不介意混淆的可能性,您当然可以使用阴影名称:

instance Eq ItemSlot where
    ItemSlot { item = item, number = a } == ItemSlot { item = item', number = a' }
        = -- use item, item', a, and a'
Run Code Online (Sandbox Code Playgroud)

为方便起见,Haskell中的模式可以嵌套; 所以,如果你想匹配ItemSlot两者都有BellPeppers,例如,你可以写

instance Eq ItemSlot where
    ItemSlot BellPepper a == ItemSlot BellPepper a' = True
    -- or, equivalently
    ItemSlot { item = BellPepper } == ItemSlot { item = BellPepper } = True
Run Code Online (Sandbox Code Playgroud)

虽然通常你会将Items 的比较委托给s的Eq实例Item.

  • 只是添加到这个:你*可以*在定义的*右* - 手边使用`item`访问器函数(或任何其他函数).所以`实例Eq ItemSlot其中is1 == is2 = item is1 == item is2`也可以.但是,模式匹配方式可能更好. (2认同)