Suggerimenti per giocare a golf a Dotty

Sep 03 2020

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

1 user Sep 03 2020 at 05:33

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(_,_))
1 user Sep 03 2020 at 23:37

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}}
1 user Sep 08 2020 at 02:00

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).

1 user Sep 04 2020 at 00:44

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}
1 user Sep 04 2020 at 00:56

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
user Sep 21 2020 at 21:32

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.

user Nov 21 2020 at 06:41

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 .