Horário de Atendimento
- Em qualquer altura: via correio electrónico pressionando aqui. Qualquer outro meio de contacto será considerado informal, não se sentindo a equipa docente vinculada a dar uma resposta em tempo útil.
- Durante o período de aulas: de acordo com o horário seguinte, sujeito a marcação verbal junto do respectivo docente:
- Essa marcação deve ser feita com um mínimo de uma semana de antecedência.
Atendimento electrónico (FAQs)
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