Suggerimenti per giocare a golf a Dotty
Quali consigli generali hai per giocare a golf a Dotty ? Sto cercando idee che possano essere applicate a problemi di codice di golf in generale che siano almeno in qualche modo specifici di Dotty (ad esempio "rimuovere commenti" non è una risposta). Si prega di inviare un suggerimento per risposta.
Vedi anche Suggerimenti per giocare a golf a Scala
Risposte
Usa la separazione dei parametri
La separazione dei parametri consente di scrivere funzioni che accettano una singola tupla come input come se fossero funzioni che accettano 2 parametri. Fondamentalmente, puoi sostituirli
list.map{case(a,b)=>a+b}
//and
list.map{case(a,b)=>Seq(a,b)}
//or
list.map(t=>t._1+t._2)
//and
list.map(t=>Seq(t._1,t._2))
con questo, che è sia più corto che più bello.
list.map(_+_)
//and
list.map(Seq(_,_))
Usa le funzioni @main e toplevel
Se è necessario creare un programma completo, utilizzare l' @mainannotazione su un metodo principale di primo livello.
@main def main={code}
È molto più breve di questi 2 approcci:
object M extends App{code}
object M{def main(a:Array[String])={code}}
Letterali numerici
È ora possibile scrivere un numero letterale per qualsiasi tipo definito dall'utente con un'istanza data / implicita del FromDigitstratto, come BigInte BigDecimal.
In Scala 2, per passare il numero 9.999.999.999.999.999 a una funzione che accetta BigInts, dovresti usare BigInt("9999999999999999"), ma ora puoi semplicemente dire direttamente 9999999999999999senza usare esplicitamente il metodo apply o il costruttore.
Puoi anche usare trattini bassi, notazione scientifica, esadecimale, ecc., Proprio come qualsiasi normale numero letterale, purché l' FromDigitsistanza di quel tipo supporti quella notazione, ovviamente. Entrambi BigInte BigDecimalvanno bene con i trattini bassi, ma BigIntconsentono solo esadecimali e BigDecimalconsentono solo la notazione scientifica (con decimali).
Bretelle opzionali
Almeno nelle espressioni di corrispondenza è possibile salvare un byte utilizzando la sintassi basata sul rientro.
a match
case b=>c
case d=>e
è 27 byte, mentre il codice seguente è 28.
a match{case b=>c case d=>e}
Come nota a margine, matchriceve anche un trattamento speciale quando si tratta di concatenare. Il seguente codice Scala 2:
("foo"match{case x=>x})match{case x=>x}
ora può essere scritto senza le parentesi:
"foo"match{case x=>x}match{case x=>x}
Escludere newcon le applicazioni dei creatori
Puoi chiamare i costruttori senza usare new(come Kotlin), trattando tutte le classi come se avessero applymetodi nei loro compagni. Ciò consente di risparmiare 4 byte ogni volta che si crea un'istanza di qualcosa, poiché new Foo()diventa giusto Foo().
Questo vale anche per i dati (anche se raramente ne hai bisogno per il golf in codice):
given foo as Foo=new Foo() //bad
given foo as Foo=Foo() //better
given foo as Foo //great
Utilizza i tipi di corrispondenza per le funzioni ricorsive che corrispondono al modello
Creare un typealias con un tipo di corrispondenza a volte è più breve rispetto all'utilizzo di una funzione appropriata. Ad esempio, prendi questa implementazione del calcolo KI (non una cosa reale). Il tipo non ha bisogno :Any, quindi risparmi 7 byte in tutto ( typeè 1 byte in più di def).
//A normal function
def r(t:Any):Any=t match{case(('K',x),y)=>r(x)case('I',x)=>r(x)case t=>t}
//With match types
type R[T]=T match{case(('K',x),y)=>R[x]case('I',x)=>R[x]case _=>T}
Certamente, in questo particolare esempio, potresti usare l'auto-tupling,, i ->valori letterali di funzione di corrispondenza del modello, ecc. Per rendere il def più breve, ma questo è solo un caso. Quando non hai a che fare con tuple, o il tipo restituito è più complesso del semplice Any, o hai più parametri, questo suggerimento diventa più utile.
Nuova sintassi di controllo
Nella maggior parte dei casi, la nuova sintassi di controllo non abbrevia il codice (ed è in realtà più prolissa), ma è utile per la comprensione. Se la tua espressione o modello termina o inizia con una parentesi o virgolette doppie, puoi salvare uno o due byte:
for((x,y,z)<-Seq((1,2,3),(3,4,5));y<-"foo")yield y+x //Old-style syntax
for(x,y,z)<-Seq((1,2,3),(3,4,5));y<-"foo"yield y+x //New control syntax
Non è utile come altre cose, come il disaccoppiamento di parametri, ma spesso mi trovo a usare per le comprensioni per chiamate di funzione come f(foo)o Seq(1,2), che terminano tra parentesi.
Guardalo correre in Scastie .