¡Esta es una revisión vieja del documento!
Puedes poner la clausula #light al principio de cada archivo de código. Esto hace que lo escrito en ese archivo permita una sintaxis más olgada, ya que por defecto F# es compatible con OCaml y este tiene una sintaxis muy restrictiva.
Para F# es importante el espaciado, es decir, los espacios tendrán relevancia en el código ya que código verticalmente alineado está considerado semánticamente relacionado.
Los comentarios serán…
// This is a single-comment. Everything from the start is treated as a comment. (* This is a multiline comment *) /// This is a doc comment that can be converted to useful documentation.
En F# cada “comando” de código es una expresión, esto significa que todo comando genera un valor de un tipo de datos concreto.
El comando open sería el equivalente a using de C#, open importa un namespace de una librería .NET (y, como en C#, necesitas hacer referencia a la DLL correspondiente).
Por defecto se agregan los siguientes namespaces: Microsoft.FSharp.Core (tipado de datos), Microsoft.FSharp.Core.Operators (operadores), Microsoft.FSharp.Collections (colecciones), Microsoft.FSharp.Control (construcciones de lazy evaluation y flujos asíncronos), Microsoft.FSharp.Text (funciones de IO).
Te permite evaluar expresiones de F#, es el ejecutable fsi.exe (con mono es fsharpi). Sobre esta podemos lanzar comandos como…
printfn "Hello world!";; #r "System.Web.dll";;
La consola evaluará el código una vez se introduzcan dos puntos y coma: ;;.
Es el “fsc.exe”.
Los datos en F# no se asignan sino que se enlazan. Esto significa que al hacer:
let x = 3
Se enlaza x con el símbolo o, en este caso, valor numérico 3, si luego se volviese a enlazar con otro valor el 3 quedaría abandonado y a la espera del garbage colector.
let soporta la asignación múltiple:
let a, b = 100, 200 // a=100, b=200 let x, y, z = 5, 4, 3 // x=5, y=4, z=3
F# soporta el tipo void para interoperar con otros lenguajes .NET y el tipo unit expresado como: (). El tipo unit significa “ningún valor” (sí, como el void).
Aunque F# puede indicar automáticamente el valor de una variable, es posible que queramos especificar el tipo de resultado mediante el nombre de este:
let a = float32 100;; let a = float32(100);; // El uso de paréntesis es opcional.
Otra forma de indicar el tipo que puede coger una variable es la siguiente (si no lo indicásemos asignaría un float):
let a : double = 100.;
Generalmente al cambiar el dato al que apunta lo que ocurre es que se crea uno nuevo y se enlaza este, pero para indicar que una variable es alterable usamos la palabra mutable; luego, para actualizar el valor utilizaremos <-:
let mutable x = 123 x <- 456
Un número, como por ejemplo 100, es interpretado como un integer de 32 bits, si queremos que sea un short escribiríamos 100s. Los tipos de datos que existen son:
La forma de expresar números es:
0x7F.0o103.0b1001.Podemos definir unidades de medida:
[<Measure>] type m (* meters *) [<Measure>] type s (* seconds *) > let distance = 123.5<m> // using meters - let time = 5.0<s> // using seconds - let speed = distance / time;; // mixing units val distance : float<m> = 123.5 val time : float<s> = 5.0 val speed : float<m/s> = 24.7
F# PowerPack (FSharp.PowerPack.dll) es una librería de Microsoft con medidas predefinidas.
Para definir strings:
let daughter = "Melissa" let pet = "Sugar"
Podemos hacer strings multi-línea:
let haiku = "No sky no earth - but still snowflakes fall"
O strings de una sóla línea en múltiples acabando estas en \ :
let haiku = "No sky\ no earth - but still\ snowflakes fall"
Podemos acceder a los carácteres:
let daughter = "kimberly" // string let first = daughter.[0] // first character, 'k' let last = daughter.[7] // last character, 'y'
O convertir el string a bytes:
> let countryBytes = "USA"B val countryBytes : byte array = [|85uy; 83uy; 65uy|]
Existen varias operaciones que podemos hacer con un string:
let fullname = "Mary "+ "Smith" // concatenation
let s = "hello " + string 100 // concatenation, string conversion operator
let len = fullname.Length // 10
let i = fullname.StartsWith("Mary") // true
También podemos construir strings largos utilizando StringBuilder:
let buf = new System.Text.StringBuilder()
buf.Append("Mary had ")
buf.Append("a little lamb, it's ")
buf.Append("(you know the rest...)")
Existe el tipo de dato boolean:
let t = true // true let f = false // false let x = t && f // false let y = t || f // true let fls = not true // false
Para evaluarlo, como en otros lenguajes, utilizamos los if's. Hemos de tener en cuenta que en F# no existe el == sino el = para hacer comparaciones de igual.
En F# el if devuelve una expresión que es asignable a una variable:
let name, pin = "bob", 123
let securityMessage =
if name = "bob" && pin = 123 then "welcome bob!"
elif name = "sally" && pin = 456 then "welcome sally!"
else "access denied"
let name = "bob"
let s =
if name="bob" then
printfn "bob is a palindrome"
"bob backwards is still bob"
else
printfn "access denied"
"who are you?"
Para no asignar un if llamaremos a ignore que recibe una expresión y la obvia:
let a, b = 100, 200 (if a < b then "a < b" else "a is not less than b") |> ignore
Los if's son expresiones que evaluan como unit.
Los bucles son expresiones que evaluan como unit.
for i = 1 to 10 do
printfn "i = %d" i
// Count from 1 to 10, with identifiers
let a, b = 1, 10
for k = a to b do
printfn "k = %d" k
// Count down from 10 (down) to 1
for j = 10 downto 1 do
printfn "j = %d" j
// Sum the first 5 non-zero integers.
// This is quite "imperative." We'll see its functional cousin later.
let mutable sum = 0
for n = 1 to 5 do
sum <- sum + n
printfn "current sum = %d" sum
// Output numbers from 1-10 and squares
let mutable n = 1
while n <= 10 do
let sq = n * n
printfn "%d %d" n sq
n <- n + 1
// Note mutable applies to both identifiers below
let mutable a, b = 1, 10
while b > a do
printfn "%d %d" a b
a <- a + 1
b <- b - 1
// Using parentheses and Boolean conjuction
let mutable a, b, c = 1, 10, 0
while ((a < b) && (c < 3)) do
printfn "%d %d %d" a b c
c <- c + 2
printfn funciona igual que String.Format:let city = "Boston" let temp = 63.5 printfn "The mean temperature for %s is %f" city temp // Imprimirá: The mean temperature for Boston is 63.500000