Информация об изменениях

Сообщение Re[11]: проектирование от 21.07.2017 3:55

Изменено 21.07.2017 4:09 dmz

Re[11]: проектирование
dmz>>Один из них, например — взять значение, и выдернуть из него все спрайты
dmz>>которые и отрисовать скопом:

F>у них есть порядок, заданный в коде.

F>а что с остальными 8999?

Ну так задать порядок в типе, или выводимый из типа, очевидно.

F>алё, ты всегда можешь объявить поле/метод со значением типа предка. чтобы потом к нему обращаться и вызывать ф-ции "базовых типов".


Не очень понял — можешь код показать? Что есть предок, например. Тут есть только композиция.
Конечно, можно напилить что-то вроде:

data Grandpa = Grapnda {...}
data Father = Father { grandpa :: Grandpa, fatherData = ... }
data Son    = Son { father = Father, sonData = ... }

-- и потом делать как-то так:

instance Drawable Son where
  draw (s@Son{..}) canvas = do
    draw (father son) -- будет и отрисовка для "предков", если инстанс для Father определен таким образом
    -- отрисовка для Son


Но это калька с Java-style ООП и так обычно не делают. Я бы просто сделал так,
что бы каждый тип содержал коллецию своих спрайтов, и выдергивал бы эти спрайты
с их атрибутами через syb. Включая порядок, который тоже можно задать разными
способами.


data OneBarrelGun = OneBarrelGun { sprites :: [Sprite] } 

-- тоже WTF, калька с Java
-- чего б нам просто не перечислить нужные спрайты и не тащить сюда
-- OneBarrelGun, если он нам не нужен на самом деле

data TwoBarrelGun = TwoBarrelGun { oneBarrel :: OneBarrelGun, twoBarrelSprites = [Sprite] } 

...


instance Monoid Canvas where

...

draw :: MonadDraw m, Data a => a -> Canvas -> m Canvas
draw a = do
  let sprites = sortBy spriteOrder [ x | x@(Sprite{..}) <- universeBi a ]
  return $ foldMap (renderSprite emptyCanvas) sprites



F>проблема в том, что в х-е 2+ уровня — это уже `considered harmful`

F>судя по синтаксису

Ну в языке, где вообще нет никакого наследования --- надо полагать.

F>да, вариант с наследованием и ручной отрисовкой — это из старых джвижков

F>в современных порядочно EntityComponentSystem, где как раз как-то это размечается в редакторе с метаинфой и автоматической отрисовкой.
F>сферически это так, да. пока не посмотришь поближе :3 если есть решение через паттерны, то я тоже буду за него благодарен.

Ну вот, привёл несколько вариантов. Да, тут нет наследования, vtbl и объектов, как смеси кода и данных.
Если всё это хочется, то надо, очевидно, использовать язык, где оно есть, зачем тогда Haskell ?

И еще надо учесть, что тут код отдельно — данные отдельно. Поэтому "наследование" в смысле Java-style OOP
особого смысла не имеет.
Re[11]: проектирование
dmz>>Один из них, например — взять значение, и выдернуть из него все спрайты
dmz>>которые и отрисовать скопом:

F>у них есть порядок, заданный в коде.

F>а что с остальными 8999?

Ну так задать порядок в типе, или выводимый из типа, очевидно.

F>алё, ты всегда можешь объявить поле/метод со значением типа предка. чтобы потом к нему обращаться и вызывать ф-ции "базовых типов".


Не очень понял — можешь код показать? Что есть предок, например. Тут есть только композиция.
Конечно, можно напилить что-то вроде:

data Grandpa = Grapnda {...}
data Father = Father { grandpa :: Grandpa, fatherData = ... }
data Son    = Son { father = Father, sonData = ... }

-- и потом делать как-то так:

instance Drawable Son where
  draw (s@Son{..}) canvas = do
    draw (father son) -- будет и отрисовка для "предков", если инстанс для Father определен таким образом
    -- отрисовка для Son


Но это калька с Java-style ООП и так обычно не делают. Я бы просто сделал так,
что бы каждый тип содержал коллецию своих спрайтов, и выдергивал бы эти спрайты
с их атрибутами через syb. Включая порядок, который тоже можно задать разными
способами.


data OneBarrelGun = OneBarrelGun { sprites :: [Sprite] } 

-- тоже WTF, калька с Java
-- чего б нам просто не перечислить нужные спрайты и не тащить сюда
-- OneBarrelGun, если он нам не нужен на самом деле

data TwoBarrelGun = TwoBarrelGun { oneBarrel :: OneBarrelGun, twoBarrelSprites = [Sprite] } 

...


instance Monoid Canvas where

...

-- Template Method!
-- на самом деле, просто функция, которая имеет дело
-- с типами, для которых есть реализации нужных тайпклассов

draw :: (MonadDraw m, Data a) => a -> Canvas -> m Canvas
draw a = do
  let sprites = sortBy spriteOrder [ x | x@(Sprite{..}) <- universeBi a ]
  return $ foldMap (renderSprite emptyCanvas) sprites



F>проблема в том, что в х-е 2+ уровня — это уже `considered harmful`

F>судя по синтаксису

Ну в языке, где вообще нет никакого наследования --- надо полагать.

F>да, вариант с наследованием и ручной отрисовкой — это из старых джвижков

F>в современных порядочно EntityComponentSystem, где как раз как-то это размечается в редакторе с метаинфой и автоматической отрисовкой.
F>сферически это так, да. пока не посмотришь поближе :3 если есть решение через паттерны, то я тоже буду за него благодарен.

Ну вот, привёл несколько вариантов. Да, тут нет наследования, vtbl и объектов, как смеси кода и данных.
Если всё это хочется, то надо, очевидно, использовать язык, где оно есть, зачем тогда Haskell ?

И еще надо учесть, что тут код отдельно — данные отдельно. Поэтому "наследование" в смысле Java-style OOP
особого смысла не имеет.