Design di oggetti mobili in Haskell

7

Supponiamo di avere un oggetto che ha un punto che denota la sua posizione e forma.

type Point = (Double, Double)

data Object =
    Object { location :: Point
           , shape    :: Shape }

dove una forma potrebbe essere come

data Shape
    = Circle { radius :: Double }
    | Rectangle { height :: Double, width :: Double }

Supponiamo che abbia una funzione che può disegnare oggetti.

draw :: [Object] -> IO ()

Fin qui non ci sono problemi.

Ora, supponiamo che voglio che gli oggetti si muovano. Quindi gli oggetti dovrebbero avere una velocità.

type Velocity = (Double, Double)

data Object =
    Object { location :: (Double, Double)
           , shape    :: Shape
           , velocity :: Velocity }

type Time = Double

move    :: Time ->  Object  ->  Object
moveAll :: Time -> [Object] -> [Object]

Il problema è che ho bisogno di un campo di velocità per spostare oggetti, ma non ne ho bisogno per disegnarli.

Penso che consentire alla funzione draw di conoscere le interruzioni di velocità dell'oggetto astrazione. Ho ragione?

Come combinare la definizione di oggetto precedente con il campo di velocità extra in ordine spostare oggetti?

  • Utilizzare tuple come (Velocity, Object) ?
  • Per includere entrambi in un nuovo tipo di dati? Se è così, allora come chiamare quel tipo di dati?

Qualsiasi suggerimento è apprezzato.

    
posta wowofbob 11.07.2016 - 15:39
fonte

2 risposte

3

Potresti dichiarare una classe di caratteri per oggetti che conoscono la loro posizione e forma e creare un'istanza per Object . Quindi il tuo draw accetta qualsiasi istanza di tale classe di caratteri, ma non sarebbe in grado di scoprire altri campi in Object .

    
risposta data 12.07.2016 - 11:29
fonte
5

Oltre a usare tuple o avvolgere Object in un nuovo tipo di dati, un'altra opzione è di parametrizzare Object con una variabile di tipo:

data Object v =
    Object { location :: (Double, Double)
           , shape    :: Shape
           , velocity :: v } deriving (Functor)

Quando si passa un oggetto al renderer, è possibile "silenziare" la velocità memorizzando un () , usando void myObject o forse usando un aggiornamento polimorfico come myObject { velocity = () } .

    
risposta data 11.07.2016 - 18:23
fonte

Leggi altre domande sui tag