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.

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)

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

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]


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



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 .


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




1

Use .NET

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

Ejemplo:

open System.Linq

¡Puede ser útil!


1

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

let f x=x*x

Se puede expresar así:

fun x->x*x


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.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.