Haskell: «сколько» типа должны получать функции? и избегая полной "реконструкции"

У меня есть следующие типы данных:

data PointPlus = PointPlus
    { coords :: Point
    , velocity :: Vector
    } deriving (Eq)

data BodyGeo = BodyGeo
    { pointPlus :: PointPlus
    , size :: Point
    } deriving (Eq)

data Body = Body
    { geo :: BodyGeo
    , pict :: Color
    } deriving (Eq)

Это базовый тип данных для персонажей, врагов, объектов и т. Д. В моей игре (ну, у меня просто есть два прямоугольника, поскольку игрок и земля прямо сейчас :p).

Когда ключ, персонажи перемещаются вправо, влево или прыгают, изменяя свою скорость. Перемещение осуществляется путем добавления скорости к коордам. В настоящее время это написано следующим образом:

move (PointPlus (x, y) (xi, yi)) = PointPlus (x + xi, y + yi) (xi, yi)

Я просто беру PointPlusчасть моего Body, а не весь Body, иначе это было бы:

move (Body (BodyGeo (PointPlus (x, y) (xi, yi)) wh) col) = (Body (BodyGeo (PointPlus (x + xi, y + yi) (xi, yi)) wh) col)

Первая версия moveлучше? Во всяком случае, если moveизменяется только PointPlus,должна быть другая функция, которая вызывает его внутри нового Body. Поясняю: есть функция update, которая вызывается для обновления состояния игры; он передает текущее состояние игры, один Bodyна данный момент, и возвращает обновленный Body.

update (Body (BodyGeo (PointPlus xy (xi, yi)) wh) pict) = (Body (BodyGeo (move (PointPlus xy (xi, yi))) wh) pict)

Это меня щекочет. Все сохранено в Body, за исключением PointPlus. Есть ли способ избежать этой полной «реконструкции» вручную? Например:

update body = backInBody $ move $ pointPlus body

Без необходимости определять backInBody, конечно.

10
задан L01man 10 June 2012 в 10:06
поделиться