From 9092e50b91c5a299a3319513571e5c73e6d2f9c4 Mon Sep 17 00:00:00 2001 From: Pedro Correa Date: Tue, 21 Jun 2022 23:33:46 +0000 Subject: [PATCH] :sparkles: haskell studies * Conditions * Functions * Lists --- Haskell/Conditions.org | 91 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Haskell/Functions.org | 35 +++++++++++++++++++++++++++++++++++ Haskell/Lists.org | 191 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 file(s) changed, 317 insertion(s)(+), 0 deletion(s)(-) diff --git a/Haskell/Conditions.org b/Haskell/Conditions.org new file mode 100644 --- /dev/null +++ b/Haskell/Conditions.org @@ -0,0 +1,91 @@ +* Condicionais +E como toda linguagem de programacao, tambem temos condicionais para criar logicas nos nossos codigos. + +*lembrete que a identacao de nosso codigo eh de extrema importancia* + +#+begin_src haskell +:{ +signum :: (Num a, Ord a) => a -> a +signum n = if n < 0 + then -1 + else if n == 0 + then 0 + else 1 +:} + +signum 10 +#+end_src + +#+RESULTS: +: 1 + +#+begin_src haskell +:{ +raizes2GrauV4 :: (Ord a, Floating a) => a -> a -> a -> (a, a) +raizes2GrauV4 a b c = + if delta < 0 + then error "Delta negativo" + else (x1, x2) + where + x1 = ((-b) + sqDelta) / (2 * a) + x2 = ((-b) - sqDelta) / (2 * a) + sqDelta = sqrt delta + delta = b^(2 :: Int) - 4 * a * c +:} + +raizes2GrauV4 2 3 5 +#+end_src + +#+RESULTS: +#+begin_example +,*** Exception: Delta negativo +CallStack (from HasCallStack): + error, called at :55:8 in interactive:Ghci19 +#+end_example + +** Guards +Tambem para facilitar a leitura e diminuir a verbosidade, podemos utilizar o *Guards* nas nossas funcoes para declarar a mesma encadeacao de condicionais feitas. +#+begin_src haskell +:{ +signumV2 :: (Num a, Ord a) => a -> a +signumV2 n + | n < 0 = -1 + | n == 0 = 0 + | otherwise = 1 +:} + +signumV2 (-20) +#+end_src + +#+RESULTS: +: ghci> +: :96:1-14: warning: [-Wtype-defaults] +: • Defaulting the following constraints to type ‘Integer’ +: (Show a0) arising from a use of ‘print’ at :96:1-14 +: (Num a0) arising from a use of ‘it’ at :96:1-14 +: (Ord a0) arising from a use of ‘it’ at :96:1-14 +: • In a stmt of an interactive GHCi command: print it +: -1 + +** Pattern Matching +Ou podemos tambem criar pattern matching para deixar as nossas declaracoes de funcoes mais explicitas e sem sintaxe de logica no nosso codigo, apenas declarando algumas verdades para serem executadas e avalidas mais tarde. + +#+begin_src haskell +:{ +soma 0 y = y +soma x 0 = x +soma x y = x + y +:} +#+end_src + +Ou podemos ignorar completamente as variavel nas nossas declaracoes de variavel nos pattern matching utilizando o ~_~ como parametro +#+begin_src haskell +:{ +mult 0 _ = 0 +mult _ 0 = 0 +mult 1 y = y +mult x 1 = x +mult x y = x * y +:} +#+end_src + diff --git a/Haskell/Functions.org b/Haskell/Functions.org new file mode 100644 --- /dev/null +++ b/Haskell/Functions.org @@ -0,0 +1,35 @@ +* Assinatura de funcao +As assinaturas de funcoes servem para declarar a tipagem que nossa funcao ira usar, retornar e os parametros que utilizaremos na funcao. + +#+begin_src haskell +:{ +raizes2Grau :: Floating a => a -> a -> a -> (a, a) +raizes2Grau a b c = (((-b) + sqrt(b^(2 :: Int) - 4 * a * c))/ (2 * a), + ((-b) - sqrt(b^(2 :: Int) - 4 * a * c))/ (2 * a)) +:} + +raizes2Grau 2 3 5 +#+end_src + +#+RESULTS: +: (NaN,NaN) + +** Clausula "where" +Para facilitar a leitura e dividir as funcionalidades e facilitar a leitura, podemos declarar trechos do codigo para variaveis dentro da funcao a fim de facilitar a leitura e poder reaproveitar codigo dentro de nossas funcoes. + +#+begin_src haskell +:{ +raizes2GrauV2 :: Floating a => a -> a -> a -> (a, a) +raizes2GrauV2 a b c = (x1, x2) + where + x1 = ((-b) + sqDelta) / (2 * a) + x2 = ((-b) - sqDelta) / (2 * a) + sqDelta = sqrt delta + delta = b^2 - 4 * a * c +:} + +raizes2GrauV2 2 3 (-5) +#+end_src + +#+RESULTS: +: (1.0,-2.5) diff --git a/Haskell/Lists.org b/Haskell/Lists.org new file mode 100644 --- /dev/null +++ b/Haskell/Lists.org @@ -0,0 +1,191 @@ +* Listas +Listas em Haskell tem o mesmo comportamento de listas ligadas, podemos declarar elas da seguinte forma +#+begin_src haskell +1 : 2 : 3 : [] +#+end_src + +#+RESULTS: +: [1,2,3] + +Temos tambem o /sugar syntax/ para declarar listas da forma mais casual e esperada +#+begin_src haskell +[1, 2, 3] +#+end_src + +#+RESULTS: +: [1,2,3] + +Com isso, podemos aproveitar para gerar listas de forma lazy (e ate listas infinitas) +#+begin_src haskell +[1..10] +#+end_src + +#+RESULTS: +: [1,2,3,4,5,6,7,8,9,10] + +#+begin_src haskell +:{ +indexa :: [a] -> Int -> a +indexa xs i = head (drop i xs) +:} + +xs = [0..200] +xs `indexa` 35 +#+end_src + +#+RESULTS: +: 35 + +#+begin_src haskell +:{ +fatorial :: Integer -> Integer +fatorial n = product [2..n] +:} + +fatorial 10 +#+end_src + +#+RESULTS: +: 3628800 + +** List Comprehension + +Desta maneira eh chamada de compreensao de listas +#+begin_src haskell +[x | x <-[0,2..100], x `mod` 6 == 0] +#+end_src + +#+RESULTS: +| 0 | 6 | 12 | 18 | 24 | 30 | 36 | 42 | 48 | 54 | 60 | 66 | 72 | 78 | 84 | 90 | 96 | + +Podemos tambem usar duas expressoes geradoras ao mesmo tempo +#+begin_src haskell +[(x, y) | x <-[0..5], y <-[11..16]] +#+end_src + +#+RESULTS: +| 0 | 11 | +| 0 | 12 | +| 0 | 13 | +| 0 | 14 | +| 0 | 15 | +| 0 | 16 | +| 1 | 11 | +| 1 | 12 | +| 1 | 13 | +| 1 | 14 | +| 1 | 15 | +| 1 | 16 | +| 2 | 11 | +| 2 | 12 | +| 2 | 13 | +| 2 | 14 | +| 2 | 15 | +| 2 | 16 | +| 3 | 11 | +| 3 | 12 | +| 3 | 13 | +| 3 | 14 | +| 3 | 15 | +| 3 | 16 | +| 4 | 11 | +| 4 | 12 | +| 4 | 13 | +| 4 | 14 | +| 4 | 15 | +| 4 | 16 | +| 5 | 11 | +| 5 | 12 | +| 5 | 13 | +| 5 | 14 | +| 5 | 15 | +| 5 | 16 | + +** Concat + +Its the same as a flatten from languages +#+begin_src haskell +concat [[1,2,4], [6,7,8]] +#+end_src + +#+RESULTS: +| 1 | 2 | 4 | 6 | 7 | 8 | + +** Creating ~length~ with list comprehension +#+begin_src haskell +tam xs = sum [1 | _ <- xs] + +tam [1..10] +#+end_src + +#+RESULTS: +: Prelude> 10 + +* Recursion +Aqui em Haskell nao temos stack overflow, como as funcoes sao de forma lazy ele ira a cada vez da recursao substituir com os novos valores na expressao. +Seguindo o exemplo seguinte de fatorial: +#+begin_src haskell +:{ +fatorial2 :: Integer -> Integer +fatorial2 0 = 1 +fatorial2 n = n * fatorial2 (n - 1) +:} + +fatorial2 3 +#+end_src + +#+RESULTS: +: Prelude> 6 + +A execucao do ~fatorial2~ seria dessa forma: +#+BEGIN_EXAMPLE += 3 * fatorial2 (3 - 1) += 3 * 2 * fatorial2 (2 - 1) += 3 * 2 * 1 * fatorial2 (1 - 1) += 3 * 2 * 1 * 1 +#+END_EXAMPLE + +Com isso, o Haskell nao ira criar uma pilha de execucao como visto em outras linguagens + +** Tail recursion +Para um exemplo de tail recursion, podemos usar um exemplo para realizar o mdc +#+begin_src haskell +:{ +mdc :: Int -> Int -> Int +mdc a 0 = a +mdc a b = mdc b (a `mod` b) +:} + +mdc 48 18 +#+end_src + +#+RESULTS: +: Prelude> 6 + +Neste exemplo, diferente do modo recursivo que a cada iteracao ira ser substituido os valores e aumentando o tamanho de nossa expressao, neste exemplo de MDC a gente mantem um tamanho fixo de expressao e de pilha. +O Haskell ira realizar as seguintes operacoes: +#+BEGIN_EXAMPLE += mdc 48 18 += mdc 18 12 += mdc 12 6 += mdc 6 0 += 6 +#+END_EXAMPLE + +* Quick Sort implementation +#+begin_src haskell +:{ +qsort :: Ord a => [a] -> [a] +qsort [] = [] +qsort (x:xs) = + (qsort menores) ++ [x] ++ (qsort maiores) + where + menores = [e | e <- xs, e < x] + maiores = [e | e <- xs, e >= x] +:} + +qsort [6,7,5,3,4,20,4444,6,89,4] +#+end_src + +#+RESULTS: +: Prelude> [3,4,4,5,6,6,7,20,89,4444] -- tangled.sh