Consejos para jugar golf en F #

21

¿Qué consejos generales tienes para jugar al golf en F #? Estoy buscando ideas que puedan aplicarse a los problemas de golf de código en general que sean al menos algo específicos para F # (por ejemplo, "eliminar comentarios" no es una respuesta). Por favor, publique un consejo por respuesta.

ProgramFOX
fuente

Respuestas:

9

Usar en functionlugar de matchcuando sea posible; guardará 6 caracteres para variables de 1 carácter:

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

vs

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

También puede reemplazar cualquier coincidencia de patrón para guardar constantemente 1 personaje:

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

¿Necesita usar un método en variable para el cual aún no ha restringido el tipo? Simplemente compárelo con un literal del tipo que desea que sea y luego deseche el resultado para anotar el tipo de esa variable:

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

Use la notación de prefijo para los operadores de infijo cuando pueda; le ahorrará tener que definir una función para usarlos.

Por ejemplo, puedes convertir esto:

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

dentro de esto:

List.map((+)2)[1;1;2;3;5;8]
Roujo
fuente
1
Lo uso aquí, gracias!
aloisdg dice Reinstate Monica el
5

Deconstrucción de tuplas

En caso de que no pueda usar variables, use la deconstrucción de tuplas en lugar de múltiples expresiones let

let a,b ="",[]

en lugar de

let a=""
let b=[]

Lectura de stdin

La biblioteca central de F # define un alias para System.Console.Inllamado stdin. Estos le permiten leer la entrada.

// Signature:
stdin<'T> :  TextReader

TextReader en msdn

La gran ventaja, aparte del hecho de que es más corto de lo que Consolees, tampoco tiene que abrir el Sistema

Iterando sobre la cuerda

La cadena es básicamente una char seq, esto le permite usar Seq.mapdirectamente con cadenas. También es posible usarlos en comprensiones[for c in "" do]

Mutables / Celdas de referencia

El uso de celdas de referencia no siempre es más corto, ya que cada operación de lectura viene con un carácter adicional para desarmar la celda.

Consejos generales

  • Es posible escribir la match .. withlínea completa

    function|'a'->()|'b'->()|_->()
    
  • No hay necesidad de espacios en blanco antes y después de los caracteres no alfanuméricos.

    String.replicate 42" "
    if Seq.exists((<>)'@')s then
    if(Seq.exists((<>)'@')s)then
    
  • En caso de que necesite rellenar una cadena con espacios a la izquierda o a la derecha, puede usar las banderas [s] printf [n] para eso.

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

    Módulo Core.Printf

Brunner
fuente
4

Use id en lugar de x-> x

id es un operador que representa la función de identidad.

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

puede ser escrito

let u x=x|>Seq.countBy id

fuente

Lo uso aqui

aloisdg dice Reinstate Monica
fuente
3

Eta-conversión para funciones

Muchas gracias a Laikoni por este consejo en una de mis soluciones .

Considere una función para, por ejemplo, sumar una cadena con 3 para letras mayúsculas y 1 para todos los demás caracteres. Entonces:

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

Mediante eta-conversion, esto puede reescribirse como:

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

y llamado de la misma manera que antes:

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

La función operador de composición directa >>

Ahora suponga que nuestro desafío original sería sumar una cadena con 3 para letras mayúsculas y 1 para letras minúsculas, y todos los demás caracteres están excluidos.

Podríamos escribir esto como:

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

Podemos usar el operador de composición directa ( >>) para encadenar las dos funciones ( Seq.filtery Seq.sumBy) juntas. Con eta-conversion la definición de la función sería:

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

Chris Smith hizo una gran reseña sobre el >>operador en su blog de MSDN .

Ciaran_McCarthy
fuente
2

Cuando sea posible Seqes más corto que List:

[[1];[2;3];[4];[5]|>List.collect
[[1];[2;3];[4];[5]|>Seq.collect

es un char más corto ...

pensar antes de codificar
fuente
2

Evite los paréntesis cuando use un parámetro y en tupla

let f = [(0,1);(1,4)]|>Seq.map(fst)
printfn "%A" f

puede ser escrito

let f = [0,1;1,4]|>Seq.map fst
printfn "%A" f
aloisdg dice Reinstate Monica
fuente
1
Tampoco necesita () alrededor de las tuplas: let f = [0,1; 1,4] |> Seq.map fst
thinkbeforecoding
1
Gracias. actualizado.
aloisdg dice Reinstate Monica
2

Prefiere una nueva cadena de línea sobre "\ n"

Esto comenzará a pagar incluso con un solo carácter de línea nueva en su código. Un caso de uso podría ser:

(18 bytes)

string.Concat"\n"

(17 bytes)

string.Concat"
"

Inspirado en la respuesta de Chiru para es6 .

Utilizado aquí

aloisdg dice Reinstate Monica
fuente
1

Use .NET

.NET ofrece muchas buenas construcciones. F # puede usarlos, ¡así que no los olvides!

Ejemplo:

open System.Linq

¡Puede ser útil!

aloisdg dice Reinstate Monica
fuente
1

Use lambdas para guardar un byte. Por ejemplo, esto:

let f x=x*x

Se puede expresar así:

fun x->x*x
dana
fuente
1

Use para ... en lugar de para ... para caminar un rango

for i in[0..2]
for i=0 to 2
aloisdg dice Reinstate Monica
fuente
1

La modulepalabra clave se puede usar para acortar los nombres de los módulos cuando se usan repetidamente. Por ejemplo:

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

puede llegar a ser

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

Esto es más útil para programas más largos donde los métodos de módulo se usan repetidamente (y deben nombrarse completamente cada vez porque tienen el RequireQualifiedAccessmodificador), y permite eliminar algunos caracteres, especialmente cuando es más útil usar una matriz CLR normal (por ejemplo, mutabilidad ) que un F # seqo list.

LSM07
fuente