Para não covardes
por Octávio Turra
Para aprender algo novo, devemos esquecer conceitos antigos
-- livro de auto-ajuda
Instituto Federal
Instituto Federal
Foi onde estudei....
O humor da sua esposa, marido, namorado, rolo... etc
...Aquele filme da Marvel
Piadas ruins grudam mais fácil na memória
-- contador de piadas ruins
agora que apagamos conceitos errados
let f x = if x == 2 then 2 else x + x in f 2
$f(2) := if2 = 2then2else~2 + 2$
$f(x) := ifx > 0then~x+f(x-1)elsex$
let f x = if x > 0 then (x + f x - 1) else x
let f 2 = if 2 > 0 then 2 + (f 2 - 1) else 2
let f 2 = if 2 > 0
then 2 + (if 1 > 0 then (
if 0 > 0 -- ops...isso é falso..
-- portanto paramos
) else 1)
else 2
Bom... Daí temos a otimização de rabo...
A otimização de rabo é quando otimizamos as chamadas, pois já sabemos que ela bateu na condição
let f 2 = if 2 > 0
then 2 + (if 1 > 0 then (0) else 1)
else 2
Falando em rabo
se isso fosse uma centopéia: [0, 1, 2, 3, 4]
0
é a cabeça e o resto é o rabo
f x = let cabeca = head x; rabo = tail x in
if rabo == [] then cabeca
else cabeca + f rabo
let f x = let cabeca = head x; rabo = tail x in
if rabo == [] then cabeca
else cabeca + f rabo in f [0, 1, 2, 3, 4]
:: => 6
mas...eita.. e se a gente for mais fundo?
f (cabeca:rabo) = let cabeca = head x; rabo = tail x in
if rabo == [] then cabeca
else cabeca + f rabo
mas...ainda da pra ir mais
f [] = 0
f [cabeca] = cabeca
f [cabeca : rabo] = cabeca + f rabo
Dá tudo na mesma
Mas digamos que eu quisesse calcular quanto eu tenho na conta bancária, de acordo com as ações de saque ou depósito...
Então eu tenho duas Ações:
- Saque de Valor
- Depósito de Valor
Como eu expressaria isso em Haskell?
Primeiro, vamos criar um apelido para Valor
type Valor = Integer
Neste caso, meu valor vai ser um número inteiro
Certo, agora que tal descrevermos nossas ações?
type Valor = Integer
data Acao v = Deposito v | Saque v
Em Haskell, devemos ser explícitos, portanto, vamos dizer que nossa ação pode ser mostrada na tela, que ela é ordenável e que podemos comparar uma ação com a outra
type Valor = Integer
data Acao v = Deposito v | Saque v deriving (Show, Eq, Ord)
Lembrem-se, como uma linguagem declarativa, temos que ensinar nosso aplicativo como lidar com as coisas, então vamos ensinar o que é um Deposito e um Saque
traduzir (Deposito v) = v
traduzir (Saque v) = -v
Agora o nosso aplicativo sabe que um depósito é uma soma e um saque é uma subtração da nossa conta
Certo, precisamos criar a função que vai tratar as ações
Vamos primeiro definir os tipos:
conciliar :: [(Acao Valor)] -> Valor
Isto significa que conciliar vai receber uma coleção ([]) de Ações sobre Valores ((Acao Valor)) e vai devolver um Valor
conciliar :: [(Acao Valor)] -> Valor
conciliar acoes = foldl (+) 0 $ map traduzir acoes
agora conhecemos mais 2 funções
- map
- foldl
Basicamente é uma função que pega algo mapeável, no nosso caso a coleção de ações e aplica uma transformação, no nosso caso a tradução
Portanto, map traduzir [(Deposito 10), (Saque 5)]
vai aplicar a função traduzir a cada item e devolver [10, -5]
..
Essa é um pouco mais chatinha.... é uma função que aplica dobras (o.O) Ela vai receber uma função que tem 2 parâmetros:
(/acumulador atual -> ...)
Um valor inicial 0
e algo dobrável...
no nosso caso, nossa coleção...
o +
, como tudo no Haskell, é uma função também. A chamamos de função infixa, pois ela fica entre os 2 parâmetros que irá receber....
Então podemos traduzir assim:
(+) :: Num a => a -> a -> a
Que significa que (+)
recebe 2 parâmetros do tipo número e devolve um número ^^
Utilizamos os ()
para dizer para o nosso programa que não vamos usar nossa função infixa e sim prefixa, ou seja:
(+) 1 2 = 1 + 2
Enfim,
Nosso foldl
vai somar cada item mapeado pela nossa função map
e dar o resultado conciliado da nossa conta
Pausa estratégica para código...
O nosso desafio se chama
Vamos implementar um joguinho de aventura em texto.
Imaginemos que nosso personagem que se chama Walterly foi jogado em uma sala trancada.
Vamos dizer para Walterly o que ele deve fazer, para sair da sala
São 3 ações possívels:
- Ver Algo
- Pegar Algo
- Falar Com Alguem
- Usar Algo
- Abrir Algo
- Ok
A jogabilidade é bem simples. Começamos com uma descrição básica das sala.
O jogador vai digitar:
Fale com o segurança
E escreveremos na tela o resultado da conversa.
Digitamos
Ok
E voltamos a ter uma descrição da sala
Como nós que vamos criar o jogo, precisamos de um roteiro...
Bom, a sala tem um Segurança e uma Porta
Quando falamos com o Segurança ele deixará cair a chave
Pegamos a chave e a usamos
Enfim, abrimos a porta e vencemos
Ok, não foi o maior desafio de encarceramento do mundo, mas já dá para começar.
Entendidos?