A apresentação está carregando. Por favor, espere

A apresentação está carregando. Por favor, espere

Funções de Alta Ordem Leonardo Lucena – IFRN, 2011 Adaptação das Transparências de Graham Hutton (http://www.cs.nott.ac.uk/~gmh/book.html)http://www.cs.nott.ac.uk/~gmh/book.html.

Apresentações semelhantes


Apresentação em tema: "Funções de Alta Ordem Leonardo Lucena – IFRN, 2011 Adaptação das Transparências de Graham Hutton (http://www.cs.nott.ac.uk/~gmh/book.html)http://www.cs.nott.ac.uk/~gmh/book.html."— Transcrição da apresentação:

1 Funções de Alta Ordem Leonardo Lucena – IFRN, 2011 Adaptação das Transparências de Graham Hutton (http://www.cs.nott.ac.uk/~gmh/book.html)http://www.cs.nott.ac.uk/~gmh/book.html These slides may be used or modified for any educational purpose on a non-profit-making basis, provided that I am acknowledged as the original author.

2  Uma função é de alta-ordem se ela pega uma função como argumento ou devolve uma função como resultado. 1 def twice[T](f: T => T, x: T): T = f(f(x)) twice é de alta-ordem porque ela pega uma função como seu primeiro arqumento.

3  Idiomas comuns de programação podem ser codificados como funções dentro da própria linguagem.  Linguagens Especificas de Domínio podem ser definidas como uma coleção de funções de alta-ordem.  Propriedades Algébricas de funções de alta-ordem podem ser usadas para raciocinar sobre programas. 2

4  A função de alta-ordem map aplica uma função a cada elemento de uma lista.  Exemplo 3 class List[T] { def map[R](f:T=>R): List[R] = … } > List(1,3,5,7).map(_+1) List(2,4,6,8)

5  A função map pode ser definida de forma bem simples usando compreensão for:  Ou alternativamente, para efeito de prova, usando recursão: 4 def map[R](f:T=>R): List[R] = for(x  xs) yield f(x) def map[R](f:T=>R): List[R] = xs match { case List() => List() case y::ys => f(y)::ys.map(f) }

6  A função de alta-ordem filtro seleciona cada elemento de uma lista que satisfaz um predicado.  Exemplo: 5 class List[T] { def filter(T => Boolean): List[T] = … } > 1 to 10 filter par List(2,4,6,8,10)

7  Filter pode ser definida usando compreensão de listas:  Ou Alternativamente using recursion: 6 def filter(p: T => Boolean) = for(x  xs; if p(x)) yield x def filter(p: T => Boolean) = xs match { case List() => List() case y::ys if p(x) => y:: ys.filter(p) case y::ys => ys.filter(p) }

8  Várias funções envolvendo listas podem ser definidas usando o seguinte padrão de recursão: 7 def f[T](xs: List[T]) = xs match { case List() => v case y::ys => y  f(ys) } f mapeia a lista vazia para um valor v e qualquer lista não vazia para alguma função  aplicada para a sua cabeça e a função f aplicada ao restante.

9 8 def soma(xs: List) = xs match { case List() => 0 case x::xs => x + soma(ys) } def and(xs: List) = xs match { case List() => true case x::xs => x && and(ys) } def produto(xs: List) = xs match { case List() => 1 case x::xs => x * produto(ys) } v = 0  = + v = 1  = * v = true  = &&

10  A função de alta-ordem foldRight encapsula o padrão de recursão, com o valor v e a função  como argumentos.  Exemplos: 9 def sum(xs:List[Int]) = xs.foldRight(0)(+) def produto(xs:List[Int]) = xs.foldRight(1)(*) def or(xs:List[Boolean]) = xs.foldRight(false)(||) def and(xs:List[Boolean]) = xs.foldRight(true)(&&)

11  A função foldRight pode ser definida usando recursão: Entretando, é melhor pensar em foldRight de forma não recursiva, através da substituição simultânea de cada (::) em uma lista pofr uma função dada e Nil por um valor dado. 10 def foldRight[R](v: R, f: (T, R) => R): R = xs match { case List() => v case y::ys => f(y, ys.foldRight(v,f)) }

12 11 soma (List(1,2,3)) List(1,2,3).foldRight(0)(+) = (1::(2::(3::Nil))).foldRight(0)(+) = 1+(2+(3+0)) = 6 = Substituindo cada (::) por (+) e Nil por 0.

13 12 Produto(List(1,2,3)) List(1,2,3).foldRight(1)(*) = (1::(2::(3::Nil))).foldRight(1)(*) = 1*(2*(3*1)) = 6 = Substituindo cada (::) por (*) e Nil por 1.

14  Apesar de foldRight encapsular um padrão simples de recursão, ela pode ser usada para definir muito mais funções do que inicialmente esperado.  Lembre a função length (tamanho): 13 def length(xs: List[T]): Int = xs match { case List() => 0 case _::ys => 1 + length(xs) }

15 14 length(List(1,2,3)) length(1::(2::(3::Nil))) = 1+(1+(1+0)) = 3 = Assim, temos: def length = foldRight(0)((_, n) => 1 + n) Substitua cada (::) por ((_,n) =>1+n) e List() por 0.

16 15 def reverse[T](xs: List[T]) = xs match { case Nil => Nil case y::ys => reverse(ys):::List(y) } reverse(List(1,2,3)) reverse(1::(2::(3::Nil))) = ((Nil:::List(3)):::List(2)):::List(1) = List(3,2,1) = For example: Substitua cada (::) por ((x::xs) => xs:::List(x)) e Nil por Nil.

17  Assim, temos:  Finalmente, note que a função de agrupamento (:::) tem uma definição compacta usando foldRight: 16 def reverse[T](xs: List[T]) = xs.foldRight(Nil)((x::xs)=>xs:::List(x)) def :::(xs: List, ys: List) = xs.foldRight(ys)(::) Substitua cada (::) por (::) e Nil por ys.

18  Algumas funções recursivas de listas, como soma, são mais simples para definir usando foldRight.  Propriedades de funções definidas usando foldRight podem ser provadas usando propriedades algébricas, como fusão e a regra da banana split  Otimizações avançadas de programas podem ser mais simples se foldRight for usada em lugar de recursão explícita 17

19  A função all decide se cada elemento de uma lista satisfaz um dado predicado.  Por exemplo: 18 def all[T](p:T=>Boolean,xs:List[T]):Boolean= (for(x<-xs, if p(x)) yield x).and > all(par, List(2,4,6,8,10)) true

20  A função any decide se ao menos um dos elementos de uma lista satisfaz um predicado.  Por Exemplo 19 def any[T](p:T=>Boolean,xs:List[T]):Boolean= (for(x<-xs, if p(x)) yield x).or > any(éEspaço,"abc def“) true

21  A função takeWhile seleciona elementos de uma lista enquanto um predicado for verdade para todos os elementos.  Por exemplo: 20 Class List[T] { … def takeWhile(p:T=>Boolean):List[T]=xs match { case y::ys if p(y) => y :: ys.takeWhile(p) case _ => Nil } > "abc def".takeWhile(éAlfa) "abc"

22  A função dropWhile remove elementos enquanto um predicado for verdade para todos os elementos de uma lista.  Por exemplo 21 Class List[T] { … def dropWhile(p:T=>Boolean):List[T]=xs match { case y::ys if p(y) => ys.dropWhile(p) case ys => ys } > " abc".dropWhile(éEspaço) "abc"

23 1. Como são chamadas as funções de alta- ordem que devolvem funções? 2. Espresse a compreensão for(x<-xs, if p(x)) yield f(x) usando as funções map e filter. 3. Defina map(f) e filter(p) usando foldRight. 22


Carregar ppt "Funções de Alta Ordem Leonardo Lucena – IFRN, 2011 Adaptação das Transparências de Graham Hutton (http://www.cs.nott.ac.uk/~gmh/book.html)http://www.cs.nott.ac.uk/~gmh/book.html."

Apresentações semelhantes


Anúncios Google