Tipps zum Golfen in F #


21

Welche allgemeinen Tipps haben Sie zum Golfen in F #? Ich bin auf der Suche nach Ideen, die sich auf Code-Golf-Probleme im Allgemeinen anwenden lassen, die zumindest etwas spezifisch für F # sind (z. B. "Kommentare entfernen" ist keine Antwort). Bitte posten Sie einen Tipp pro Antwort.

Antworten:


9

Verwenden Sie functionanstelle von, matchwenn möglich; Es werden 6 Zeichen für 1-Zeichen-Variablen gespeichert:

let f=function // ... (14 chars)

vs

let f x=match x with // ... (20 chars)

Es kann auch jede Musterübereinstimmung ersetzen, um 1 Zeichen konsistent zu speichern:

match a with|          // ... (13 chars)
a|>function|           // ... (12 chars)
(function| (* ... *))a // (12 chars)

8

Müssen Sie eine Methode für Variablen verwenden, für die Sie den Typ noch nicht eingeschränkt haben? Vergleichen Sie es einfach mit einem Literal des gewünschten Typs und werfen Sie dann das Ergebnis weg, um den Typ dieser Variablen mit Anmerkungen zu versehen:

let f (x:string)=x.Length
let f x=x="";x.Length

7

Verwenden Sie die Präfixnotation für Infix-Operatoren, wenn Sie können - Sie müssen keine Funktion definieren, um sie zu verwenden.

Zum Beispiel können Sie dies drehen:

List.map(fun i->i+2)[1;1;2;3;5;8]

das mögen:

List.map((+)2)[1;1;2;3;5;8]

1
Ich benutze es hier, danke!
aloisdg sagt Reinstate Monica

5

Tupel-Dekonstruktion

Wenn Sie nicht mit Variablen umgehen können, verwenden Sie die Tupel-Dekonstruktion anstelle mehrerer let-Ausdrücke

let a,b ="",[]

anstatt

let a=""
let b=[]

Lesen von stdin

Die F # -Kernbibliothek definiert einen Alias ​​für die System.Console.Inaufgerufenen stdin. Mit diesen können Sie Eingaben lesen.

// Signature:
stdin<'T> :  TextReader

TextReader auf msdn

Abgesehen von dem großen Vorteil, dass es kürzer als Consoleist, müssen Sie System auch nicht öffnen

Über einen String iterieren

Zeichenfolge ist im Grunde genommen eine Zeichenfolge char seq, mit der Sie Seq.mapdirekt Zeichenfolgen verwenden können. Es ist auch möglich, sie in Begriffen zu verwenden[for c in "" do]

Mutables / Referenzzellen

Die Verwendung von Referenzzellen ist nicht immer kürzer, da jeder Lesevorgang ein zusätzliches Zeichen enthält, um die Zelle deref zu machen.

Allgemeine Hinweise

  • Es ist möglich, die komplette match .. withInline zu schreiben

    function|'a'->()|'b'->()|_->()
    
  • Leerzeichen vor und nach nicht alphanumerischen Zeichen sind nicht erforderlich.

    String.replicate 42" "
    if Seq.exists((<>)'@')s then
    if(Seq.exists((<>)'@')s)then
    
  • Wenn Sie eine Zeichenfolge mit Leerzeichen links oder rechts auffüllen müssen, können Sie dafür die Flags [s] printf [n] verwenden.

    > sprintf "%20s" "Hello, World!";;
    val it : string = "       Hello, World!"
    

    Core.Printf-Modul


4

Verwenden Sie id anstelle von x-> x

id ist ein Operator, der für die Identitätsfunktion steht.

let u x=x|>Seq.countBy (fun x->x)

kann geschrieben werden

let u x=x|>Seq.countBy id

Quelle

Ich benutze es hier


3

Eta-Konvertierung für Funktionen

Vielen Dank an Laikoni für diesen Tipp in einer meiner Lösungen .

Stellen Sie sich eine Funktion vor, um beispielsweise eine Zeichenfolge mit 3 für Großbuchstaben und 1 für alle anderen Zeichen zu summieren. So:

let counter input = Seq.sumBy (fun x -> if Char.IsUpper x then 3 else 1) input

Durch Eta-Konvertierung kann dies wie folgt umgeschrieben werden:

let counter = Seq.sumBy (fun x -> if Char.IsUpper x then 3 else 1)

und wie zuvor angerufen:

counter "Hello world!" |> printfn "%i"

Die Funktion zum Weiterleiten der Komposition >>

Angenommen, unsere ursprüngliche Herausforderung besteht darin, eine Zeichenfolge mit 3 für Großbuchstaben und 1 für Kleinbuchstaben zu summieren, und alle anderen Zeichen sind ausgeschlossen.

Wir könnten dies schreiben als:

let counter input = Seq.filter Char.IsLetter input |> Seq.sumBy (fun x -> if Char.IsUpper x then 3 else 1)

Wir können den Forward-Composition-Operator ( >>) verwenden, um die beiden Funktionen ( Seq.filterund Seq.sumBy) miteinander zu verketten. Bei der eta-Konvertierung würde die Funktionsdefinition folgendermaßen aussehen:

let counter = Seq.filter Char.IsLetter >> Seq.sumBy (fun x -> if Char.IsUpper x then 3 else 1)

Chris Smith hat >>in seinem MSDN-Blog einen tollen Bericht über den Betreiber verfasst .





1

Verwenden Sie .NET

.NET bietet viele nette Builtins. F # kann sie benutzen, also vergiss sie nicht!

Beispiel:

open System.Linq

Es kann hilfreich sein!


1

Verwenden Sie Lambdas, um ein Byte zu speichern. Zum Beispiel das:

let f x=x*x

Kann wie folgt ausgedrückt werden:

fun x->x*x


1

Das moduleSchlüsselwort kann verwendet werden, um Modulnamen bei wiederholter Verwendung zu verkürzen. Beispielsweise:

Array.fold ...
Seq.iter ...
List.map ...

kann werden

module A=Array
A.fold ...
module S=Seq
S.iter ...
module L=List
L.map ...

Dies ist nützlicher für längere Programme, bei denen Modulmethoden wiederholt verwendet werden (und jedes Mal vollständig benannt werden müssen, weil sie den RequireQualifiedAccessModifikator haben), und ermöglicht das Absparen einiger Zeichen, insbesondere, wenn es nützlicher ist, ein reguläres CLR-Array zu verwenden (z. B. Mutabilität) ) als ein F # seqoder list.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.