F#
Henrique Seabra, Rilter Tavares
{hsd,rtn}@cin.ufpe.br
Roteiro
 A linguagem
 Origem
 Características
 Aplicações
 Configurando o ambiente
 Sintaxe
 Referências
A Linguagem - Origem
 F# é uma linguagem de programação funcional tipada para o
Framewok .NET
 Teve origem na família ML de linguagens
 ML é uma linguagem de programação funcional de proposta
geral desenvolvida no final dos anos 1970 na Universidade de
Edimburgo, e é considerada uma linguagem funcional impura,
por permitir a programação imperativa, ao contrário de outras
linguagens funcionais como Haskell.
 É visto como uma implementação de ML para .NET
A Linguagem - Características
 F# foi projetado desde o início para dar uma boa
interoperabilidade com outras linguagens .NET
 É uma linguagem de programação de script/ functional/
imperativa/ orientada a objeto
 Possui boa performance, código sucinto, suporta generics e
pode ser compilado por outros compiladores, como o de
Ocaml
 Não é limitada ao Windows
F#: Combinando Paradigmas
Functional
Objects
Strong Typing
.NET
Tools
Visual Studio
F# Compiler
Succinct
.NET OO Model
Libraries
Type Inference
Tools
Data Types and
Patterns
1st Class Functions
Meta-Programming
F# Interactive
Concurrency
Interoperable
LINQ
Visual Studio
Integration
A Linguagem - Aplicações
 Aplicações de processamento pesado
 Sistemas de datamining
 Mercados Financeiros
 Análise estatística
 Jogos para XBOX usando XNA
Configurando o Ambiente
 Baixar a última versão disponibilizada (F# CTP release) no
link: http://research.microsoft.com/fsharp/release.aspx
 Descompactar o arquivo
 Executar o arquivo InstallFSharp.msi
Hello World
 Criar arquivo “hello.fs”
#light
printfn "Hello World"
 No prompt de comando do Windows, executar a seguinte
instrução:
“c:Arquivos de programas\FSharp-1.9.6.2\bin\fsc.exe” hello.fs
F# em 2 minutos
Inferência de tipos
let square x = x * x;;
let concat (x : string) y = x + y;;
concat "Hello, " "World!";;
Funções de primeira ordem
 Lambda expression
>List.map (fun x -> x % 2 = 0) [1 .. 10];;
Printfn
 %d, %f, e %s são, respectivamente, inteiros, floats e strings
> printfn "%d * %f = %s" 5 0.75 ((5.0 * 0.75).ToString());;
5 * 0.750000 = 3.75
Listas
let vowels = ['e'; 'i'; 'o'; 'u'];;
let cons = 'a' :: vowels;;
let sometimes = vowels @ ['y'];;
Listas
 Iter
 Percorre cada item da coleção
 Idêntico ao foreach
 Ex:
 Imprime todos os itens de uma lista
List.iter (fun i -> printfn "Has element %d" i) [1 .. 10]
Listas
 Map
 Transforma uma coleção baseada numa função
 Ex:
 Mapeia um array de inteiros para strings
Array.map (fun (i : int) -> i.ToString()) [| 1 .. 10 |]
Listas
 Fold
 Transforma ou reduz a coleção em um único valor
 Como ‘iter’ e ‘map’, também é aplicado a cada elemento
 Única que possui um parâmetro acumulativo
 Ex:
 Somatório de cada item da série (reduzir a série a um único
valor
 Parâmetro acumulador é o somatório de todos os elementos
Seq.fold (fun acc i -> i + acc) 0 { 1 .. 10 }
Sequences
 System.Collections.Generic.IEnumerator ou ‘Seq’
 Podem especificar séries infinitas
 Apenas valor atual é guardado na memória
 Exemplo de seqüência de todos os inteiros:
let allIntegers = Seq.init_infinite (fun i -> i)
Tuplas
> let tupla = (1, false, "texto");;
val tuple : int * bool * string
> let getNumberInfo (x : int) = (x, x.ToString(), x * x);;
val getNumberInfo : int -> int * string * int
> getNumberInfo 42;;
val it : int * string * int = (42, "42", 1764)
> let printBlogInfo (owner, title, url) = printfn "%s's blog [%s] is
online at '%s'" owner title url;;
val printBlogInfo : string * string * string -> unit
> let myBlog = (“Pessoa", “Nome do blog", "http://blog.com");;
val myBlog : string * string * string
> printBlogInfo myBlog;;
Pessoa's blog [Nome do blog] is online at 'http://blog.com‘
val it : unit = ()
Records
type Address = {Name:string; Address:string; Zip:int}
let whiteHouse = {Name="The White House";
Address="1600 Pennsylvania Avenue";
Zip=20500}
Option Values
 Dificuldade de achar o valor ‘null’
 Valores sempre inicializados
 Necessidade de ausência de valores
 Similar aos valores nulos de C#
 ‘Option type’ representa dois estados: ‘Some’ e ‘None’
type Person = { First : string; MI : string option; Last : string }
let billg
= {First = "Bill"; MI = Some("H"); Last = "Gates" }
let chrsmith = {First = "Chris"; MI = None;
Last = "Smith" }
Function Currying
> let addThree x y z = x + y + z;;
val addThree : int -> int -> int -> int
> let addTwo x y = addThree 10 x y;;
val addTwo : int -> int -> int
> addTwo 1 1;;
val it : int = 12
Discriminated Union
type MicrosoftEmployee =
| BillGates
| SteveBalmer
| Worker of string
| Lead of string * MicrosoftEmployee list
let printGreeting (emp : MicrosoftEmployee) =
match emp with
| BillGates -> printfn "Hello, Bill"
| SteveBalmer -> printfn "Hello, Steve"
| Worker(name) | Lead(name, _)
-> printfn "Hello, %s" name
Discriminated Union
type MicrosoftEmployee =
| BillGates
| SteveBalmer
| Worker of string
| Lead of string * MicrosoftEmployee list
| ChrisSmith
Pattern Matching
let listLength alist =
match alist with
| [] -> 0
| a :: [] -> 1
| a :: b :: [] -> 2
| a :: b :: c :: [] -> 3
| _ -> failwith "List is too big!"
let getType (x : obj) =
match x with
| :? string -> "x is a string"
| :? int
-> "x is an int"
| :? Exception
-> "x is an exception"
Operador Pipe
 let (|>) x f = f x
 'a -> ('a -> 'b) -> 'b
let double x = x + x
let toStr (x : int) = x.ToString()
let rev (x : string) = new String(Array.rev (x.ToCharArray()))
// 512 -> 1024 -> "1024" -> "4201"
let result = rev (toStr (double 512))
let result = 512 |> double |> toStr |> rev
Lazy Values
 Apenas computado quando necessário
 Ex:
> let x = lazy (printfn "Computed."; 42);;
val x : Lazy<int>
> let listOfX = [x; x; x];;
val listOfX : Lazy<int> list
> x.Force();;
Computed.
val it : int = 42
Lazy Values
 Pode ser usado para evitar computações desnecessárias ou
“caras”
 Útil na construção de valores recursivos
 Ex:
type InfiniteList =
| ListNode of int * InfiniteList
let rec circularList = ListNode(1, circularList)
 “circularList” referencia ele mesmo (loop infinito de
ListNodes com valor 1)
 Sem “Lazy Initialization”, esse tipo de valor seria impossível
 Compilador faz esse trabalho nos “bastidores”
Mais alguns exemplos
Exercício 1
 Construa uma função que recebe um Inteiro e retorna um
Booleano que indica se o referido número é primo ou não.
 Ex:


ehPrimo 3 = true
ehPrimo 1 = false
 Faça uma função que, dado um Inteiro, retorna uma lista com
todos os números primos menores ou iguais a ele.
 Ex:

primosAte 5 = [2,3,5] ou [5,3,2]
Exercício 2
 Faça uma função que retorne o elemento da folha mais à
esquerda de uma árvore.
 Ex:
 leftmost arv
 Faça uma função que retorne, da esquerda para direita, todos
os elementos de uma árvore.
 Ex:
 elementos arv
Referências
 Microsoft Research. Disponível em:
http://research.microsoft.com/fsharp/manual/lexyacc.aspx. Último acesso em:
14/05/2008
 SMITH, Chris. MSDN Blogs. Disponível em:
http://blogs.msdn.com/chrsmith/archive/2008/05/02/f-in-20-minutes-part-i.aspx.
Último acesso em: 14/05/2008
 SEMPLE,Thomas Alexander. iMasters. Disponível em:
http://imasters.uol.com.br/artigo/7750/dotnet/conheca_o_f. Último acesso em:
14/05/2008
 Wikipedia. Disponível em:
http://pt.wikipedia.org/wiki/ML_(linguagem_de_programa%C3%A7%C3%A3o).
Último acesso em: 14/05/2008
 Microsoft Research. Disponível em:
http://www.microsoft.com/france/vision/mstechdays08/WebcastMSDN.aspx?EID=1
2841bd9-158e-4dc3-bc5b-8e3d5fd7b552 . Último acesso em: 14/05/2008
 PICKERING, Robert. Foundations of F#. Apress: 2007. 360 p.
F#
Henrique Seabra, Rilter Tavares
{hsd,rtn}@cin.ufpe.br
Download

FSharp-parte1