2010-02-16 17 views
13

Ho un insieme di classi case similiCome eseguire la corrispondenza del modello con le classi di casi vararg?

abstract class Shape 
case class Rectangle(width: Int, height: Int) extends Shape 
case class Location(x: Int, y: Int, shape: Shape) extends Shape 
case class Circle(radius: Int) extends Shape 
case class Group(shape: Shape*) extends Shape 

dove in sostanza Group è una matrice di forme. Devo definire un metodo di dimensione per calcolare le dimensioni per il rettangolo, il cerchio e la posizione, è semplice restituirne uno. Ma sto avendo difficoltà per il gruppo.

object size extends Shape{ 
    def size(s: Any) : Int = s match { 
    case Rectangle(x,y) => 1 
    case Group // how to do it? Also having case Group(shape : Shape*) gives an error 
    case Circle(r) => 1  
    case Location(x,y,shape) => 1 
    } 
} 

So per il gruppo ho bisogno di usare la mappa e piegare a sinistra, ma davvero non posso creare una logica per questo. Grazie

risposta

8

La sintassi per la corrispondenza del modello vararg è in qualche modo strange.

def size(s: Shape) : Int = s match{ 
    case Rectangle(x,y) => 1 
    case Circle(r) => 1 
    case Location(x,y,shape) => 1 
    case Group(shapes @ _*) => (0 /: shapes) { _ + size(_) } 
} 

noti che nell'ultima riga, si somma delle dimensioni di tutti i sub-shapes partendo da zero utilizzando il -notation /: per pieghe.


Come folds lavoro: Folds accumulano gli elementi di una sequenza utilizzando una data funzione.

Quindi, al fine di calcolare la somma di una lista, avremmo scritto (in stile Haskell)

fold (\total element -> total + element) 0 list 

che combinare tutti gli elementi della lista con la data funzione aggiunta a partire da 0 (e quindi calcolare la somma).

In Scala, possiamo scrivere in questo modo:

(0 /: list) { (total, element) => total + element } 

che può essere semplificato per

(0 /: list) { _ + _ } 
+0

Questo non tiene conto delle sovrapposizioni. È importante? – PanCrit

+0

puoi spiegarmi come funziona l'ultima linea troppo strana ????? case Group (shapes @ _ *) => (0 /: shapes) {_ + size (_)} – tom

+0

@PanCrit: Non sono così fluente in Scala - Potresti spiegare cosa si intende con * sovrapposizione *, per favore ? – Dario

17

Uno di questi funziona, il secondo è probabilmente preferito se un po 'strano in un primo momento occhiata. Vedi 8.1.9 Sequenze di pattern da Scala Reference.

case g: Group => g.shape.map(size(_)).sum 

case Group(ss @ _*) => ss.map(size(_)).sum 

Questo sta utilizzando Scala 2.8. sum potrebbe non funzionare su versioni precedenti.

+0

Questo non tiene conto delle sovrapposizioni. È importante? – PanCrit

+5

La mia ipotesi è che la domanda riguardi la corrispondenza dei pattern in Scala piuttosto che in geometria. – retronym

2

Il primo passo è capire cosa intendi. Le due scelte più ovvie sono l'area totale coperta da tutte le forme e il rettangolo minimo che le contiene tutte. Se per i cerchi si restituisce l'area effettiva, è probabile che si debba andare con l'area effettiva.

Non esiste un modo chiuso per rispondere a questa domanda. Potrei considerare di lanciare un migliaio di freccette casuali in un rettangolo che racchiude il minimo e di stimare l'area come la percentuale di frecce che colpiscono un punto occupato. Una stima è una risposta accettabile?

Sei sicuro che tutte le forme saranno cerchi e rettangoli? Potresti riuscire a mettere insieme una soluzione che potrebbe funzionare per loro. Se le forme potrebbero essere ulteriormente estese, allora non funzionerà.

0

caso g:. Gruppo => g.shape.map (dimensioni (_)) riassumono

caso Group (ss @*) => ss.map (dimensioni ()).somma

entrambe queste indica la somma in valore di errore non è membro di Seq [Int]
Tuttavia questo OEN funziona
caso del Gruppo (forme @ _ *) => (0 /: forme) {_ + dimensioni (_)

+2

Si prega di non inviare domande come risposte, ma modificare la tua domanda! – Dario

1

per Località dimensioni dovrebbero drill-down per ottenere dimensioni in quanto la forma potrebbe essere gruppo che fa sì che un numero più elevato

caso Location (x, y, forma) => dimensioni (forma)

Quello è se la dimensione è il numero di forme nella forma

Problemi correlati