Dia | Hora | Cursos![]() | Docente |
---|---|---|---|
3.ª-feira | 09h00-10h00 | LCC | J.N. Oliveira |
5.ª-feira | 11h00-12h00 | LCC | O.M. Pacheco |
2.ª-feira | 18h00-20h00 | LEI | L.S. Barbosa |
5.ª-feira | 18h00-19h00 | LEI | J.N. Oliveira |
5.ª-feira | 18h00-20h00 | LEI | L.S. Barbosa |
6.ª-feira | 14h00-17h00 | LEI | O.M. Pacheco |
FAQ1 - Como mostro a igualdade entre (f . id) x (g + id).i1 e f x (g + id) . ( id x i1)?
R: O problema é a falta de uns parênteses: para f x (g + id) . ( id x i1) tipar bem é preciso colocar parênteses à esquerda da composição: (f x (g + id)) . ( id x i1). Depois é só aplicar a lei functor-x. NB: na nossa notação a composição tem prioridade sobre qualquer outro combinador.
FAQ2 - Gostaria de saber se a função (A x C + B x D) -- [pi2,pi2] --> C + D está bem tipada.
R: Para estar era preciso que as duas instâncias de pi2 tivessem o mesmo tipo de saída. Ora isso não acontece: tem-se A x C -- pi2 --> C num caso e B x D -- pi2 --> D no outro, ambos diferentes de C + D. Isto explica o que se deve fazer: escrever pi2 + pi2 em vez de [pi2,pi2].
FAQ3 - Como devo abordar a questão 6 do Teste de LEI do ano de 2009?.
R: O tipo From a é definido por data From a = First a | Next (From a) na questão 4.
Logo tem-se From a isomorfo a F(From a), para F X = a + X e F f = id + f. Tem-se ainda in = [First,Next] e
out(First a) = i1 a out(Next x) = i2 x
Para converter rev num hilo deste tipo teremos que encontar os seus dois genes divide e conquer tais que aux = conquer . (F aux) . divide. Pelo tipo _aux :: ([a], [a]) -> [a]: vê-se que os tipos têm de ser
divide : [a] x [a]->([a] x [a])
e
conquer : F [a] -> [a]
Das cláusulas
aux([],l) =l aux(h:t,l) = aux (t,h:l)
infere-se
divide([],l) = i1 l divide (h:t,l) = i2(t,h:l)
Como nada acontece após a chamada recursiva nessas mesmas cláusulas, ter-se-á
conquer = [id,id]
Para ver isto a funcionar implemente-se em Haskell:
data From a = First a | Next (From a) deriving Show
inF = either First Next
outF(First a) = i1 a
outF(Next x) = i2 x
cataF h = h . recF (cataF h) . outF
recF f = id -|- f
anaF g = inF . (recF (anaF g) ) . g
hyloF g h = cataF g . anaF h
divide([],l) = i1 l
divide (h:t,l) = i2(t,h:l)
conquer = either id id
Ver-se-á que, por exemplo,
hyloF conquer divide ([1,2,3],[4,5]) == aux([1,2,3],[4,5]) etc
FAQ4 - Tenho uma dúvida na última propriedade do exercício 2 (Ficha nr 4): pegando na primeira parte da igualdade e usando duas vezes a propriedade (53) do formulário, obtenho [[a,b].p?,[c,d].p?].p? Posso neste momento posso usar a propriedade (20), absorçao-+? Assim obtinha [[a,b],[c,d]].(p?+p?).p? de onde prossigo usando (3) da mesma ficha.
R: Claro que sim, esse é o caminho a seguir. De um modo geral, sempre que tiver uma alternativa de (quaisquer) composições a lei é aplicável, dando uma composição de uma alternativa com uma soma.
FAQ5 - Gostaria de perceber melhor a razão para haver uma notação funcional com variáveis ("pointfree") e outra sem elas ("pointwise") e qual se deve escolher e em que circunstâncias.
Sem variáveis os programas ficam reduzidos a expressões algébricas sobre as quais se pode raciocinar usando o Cálculo de Programas. Após os cálculos (eg. conversão da função de Fibonacci - recursiva e ineficiente -- num ciclo -- não recursivo, eficiente ) converte-se o resultado final de novo para Haskell com variáveis e... "entrega-se ao cliente". Se tentar fazer o mesmo sempre com variáveis os cálculos terão que usar provas por indução matemática e serão mais longos e (para muitos) difíceis de perceber.
-- JoseNunoOliveira - Página criada em 14 Feb 2012