2

У меня есть следующие данные, которые могут иметь корабль или нет:Haskell: если-то-иначе блоки и данные с асимметричными конструкторами

data LaserCollisionResult = NoCollision | LaserToLaserCollision Ship | LaserToShipCollision Ship deriving (Eq, Show) 

затем, позже, я пытаюсь проверить, если LaserCollisionResult является типа LaserToLaserCollision, но я получаю сообщение об ошибке. Моя [лямбда] функция заключается в следующем:

laserPaths' = map (\(p,r) -> if r == LaserToLaserCollision then doSomethingWith p else p) $ zip laserPaths laserCollisionResults 

Ошибка я получаю:

Couldn't match type 'LaserCollisionResult' with 'Ship -> LaserCollisionResult' 
Expected type: [Ship -> LaserCollisionResult] 
Actual type: [LaserCollisionResult] 
In the second argument of 'zip', namely laserCollisionResults. 

Как я могу проверить, является ли LaserCollisionResult в laserCollisionResults имеет тип LaserToLaserCollision?

+2

'map f $ zip xs ys' - это то же самое, что и' zipWith (curry f) xs ys'. Вы можете упростить 'laserPaths''' zipWith (\ p r -> case r of {...}) laserPaths laserCollisionResults'. – Cirdec

+0

@Cirdec Спасибо за это. –

ответ

2

Необходимо сопоставить на r, например.

laserPaths' = map (\(p,r) -> if isLaserCollision r then doSomethingWith p else p) $ zip laserPaths laserCollisionResults 
    where isLaserCollision (LaserToLaserCollision _) = True 
     isLaserCollision _ = False 

или вы можете соответствовать рядный:

laserPaths' = map (\(p, r) -> case r of { (LaserToLaserCollision _) -> doSomethingWith p ; _ -> p}) $ zip laserPaths laserCollisionResults 
5

Заменить лямбда на

(\(p,r) -> case r of {LaserToLaserCollision _ -> doSomethingWith p; _ -> p}) 

Кстати, для этого вам не нужно вывести Eq экземпляр.