Haskell中的类型和类型类:记录构造中缺少字段

old*_*123 1 constructor haskell exception record

我有三种数据类型:

data Person = Person { firstName :: String  
                     , lastName :: String  
                     , age :: Int  
                     , height :: Float  
                     , phoneNumber :: String  
                     , flavor :: String  
                     } deriving (Eq,Show, Read) 

data Car = Car {company :: String, model :: String, year :: Int} deriving (Eq,Show,Read)  

data Things = C Car | P Person deriving (Eq,Show,Read) 
Run Code Online (Sandbox Code Playgroud)

我想在[[Things]]中找到Car的坐标.

我试过了:

enumerate = zip [0..]

findCar :: [[Things]] -> [(Int, Int)]
findCar things = do
        [(x, y)
          | (y, row) <- enumerate things
          , (x, thing) <- enumerate row
          , thing == C (Car { })]
Run Code Online (Sandbox Code Playgroud)

但是我得到了一个例外:'在唱片公司缺少领域'.

如何以正确的方式在[[Things]]中找到Car的坐标?

Dan*_*ner 5

而不是检查你thing是否等于特定的Car,这是什么(==),你似乎想要检查它是否是任何一种Car.所以:

isCar (C Car{}) = True
isCar _ = False

findCar things =
    [ (x, y)
    | (y, row) <- enumerate things
    , (x, thing) <- enumerate row
    , isCar thing
    ]
Run Code Online (Sandbox Code Playgroud)

(我删除了不必要的和可能混淆dofindCar.)

或者,您可以在列表推导中使用失败模式匹配的行为:

findCar things =
    [ (x, y)
    | (y, row) <- enumerate things
    , (x, C Car{}) <- enumerate row
    ]
Run Code Online (Sandbox Code Playgroud)

这是一个众所周知的技巧,但有点微妙,可能会在快速读取代码时感到困惑(因为匹配看起来很偏,但不是),因此在许多程序员之间共享的代码库中可能值得避免.