320 likes | 394 Vues
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
E N D
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
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” • No prompt de comando do Windows, executar a seguinte instrução: #light printfn "Hello World" “c:Arquivos de programas\FSharp-1.9.6.2\bin\fsc.exe” hello.fs
Inferência de tipos let square x = x * x;; letconcat (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 %ssão, respectivamente, inteiros, floats e strings > printfn"%d * %f = %s" 5 0.75 ((5.0 * 0.75).ToString());; 5 * 0.750000 = 3.75
Listas letvowels = ['e'; 'i'; 'o'; 'u'];; letcons = '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 (funi->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} letwhiteHouse = {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 } letbillg = {First = "Bill"; MI = Some("H"); Last = "Gates" } letchrsmith = {First = "Chris"; MI = None; Last = "Smith" }
Function Currying > letaddThree x y z = x + y + z;; valaddThree : int->int->int->int > letaddTwo x y = addThree 10 x y;; valaddTwo : int->int->int > addTwo 1 1;; valit : int = 12
Discriminated Union typeMicrosoftEmployee = | BillGates | SteveBalmer | Workerof string | Lead of string * MicrosoftEmployeelist 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 letlistLengthalist = matchalistwith | [] -> 0 | a :: [] -> 1 | a :: b :: [] -> 2 | a :: b :: c :: [] -> 3 | _ ->failwith"List is too big!" letgetType (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 letdouble x = x + x lettoStr (x : int) = x.ToString() letrev (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> > letlistOfX = [x; x; x];; vallistOfX : 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: typeInfiniteList = | ListNodeofint * InfiniteList letreccircularList = 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”
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: • leftmostarv • 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=12841bd9-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