~misterio/veraoPFPA-Listas

6412b58fc33cb45de1c059ada148fffab0190150 — Gabriel Fontes 5 months ago
lista: adiciona ex 1 ao 4
5 files changed, 311 insertions(+), 0 deletions(-)

A .gitignore
A flake.lock
A flake.nix
A lista.md
A pdf.nix
A  => .gitignore +1 -0
@@ 1,1 @@
*.pdf

A  => flake.lock +43 -0
@@ 1,43 @@
{
  "nodes": {
    "flake-utils": {
      "locked": {
        "lastModified": 1644229661,
        "narHash": "sha256-1YdnJAsNy69bpcjuoKdOYQX0YxZBiCYZo4Twxerqv7k=",
        "owner": "numtide",
        "repo": "flake-utils",
        "rev": "3cecb5b042f7f209c56ffd8371b2711a290ec797",
        "type": "github"
      },
      "original": {
        "owner": "numtide",
        "repo": "flake-utils",
        "type": "github"
      }
    },
    "nixpkgs": {
      "locked": {
        "lastModified": 1644033087,
        "narHash": "sha256-beskas17YPhrcnanzywake9/z+k+xOWmavW24YUN8ng=",
        "owner": "NixOS",
        "repo": "nixpkgs",
        "rev": "9f697d60e4d9f08eacf549502528bfaed859d33b",
        "type": "github"
      },
      "original": {
        "owner": "NixOS",
        "ref": "nixos-unstable",
        "repo": "nixpkgs",
        "type": "github"
      }
    },
    "root": {
      "inputs": {
        "flake-utils": "flake-utils",
        "nixpkgs": "nixpkgs"
      }
    }
  },
  "root": "root",
  "version": 7
}

A  => flake.nix +36 -0
@@ 1,36 @@
{
  description = "Lista 1 de PFPA";

  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
    flake-utils.url = "github:numtide/flake-utils";
  };

  outputs = { self, nixpkgs, flake-utils }:
    flake-utils.lib.eachDefaultSystem (system:
      let
        pkgs = import nixpkgs { inherit system overlays; };
        overlay = final: prev: {
          pdf = final.callPackage ./pdf.nix { };
        };
        overlays = [ overlay ];
      in
      rec {
        packages.pdf = pkgs.pdf;
        defaultPackage = packages.pdf;

        devShell = pkgs.mkShell {
          inputsFrom = [ defaultPackage ];
          buildInputs = with pkgs; [
            # Haskell toolchain
            ghc
            stack
            # LSP
            haskell-language-server
            # Watch build
            inotifyTools
          ];
        };
      });
}


A  => lista.md +218 -0
@@ 1,218 @@
<!-- name: main
```haskell
main = print $ \
```
-->

# Lista 1 - PFPA

Gabriel Silva Fontes

## 1. Construa o _list comprehension_ que gere:

### a) [0,5,10,15,20,25,30,35,40,45,50]

*Solução*:
<!-- require: main -->
```haskell
    [ x | x <- [0,5..50]]
```


### b) uma lista de 'a' a 'z' sem vogais.

*Solução*:
<!-- require: main -->
```haskell
    [ x | x <- ['a'..'z'], not $ x `elem` "aeiou" ]
```


### c) uma lista de 0 a 50 sem os números 2, 7, 13, 35 e 42

*Solução*:
<!-- require: main -->
```haskell
    [ x | x <- [0..50], not $ x `elem` [2,7,13,35,42]]
```


### d) [500.0, 250.0, 125.0, 62.5, 31.25, 15.625, 7.8125, 3.90625, 1.953125, 0.9765625]

*Solução*:
<!-- require: main -->
```haskell
    [ 500 / 2^x | x <- [0..9] ]
```


### e) uma lista com todas as coordenadas de um tabuleiro de damas 8x8

*Solução*:
<!-- require: main -->
```haskell
    [ (x, y) | x <- ['a'..'h'], y <- [1..8] ]
```


## 2. Crie as funções da forma como solicitado:


### a) Crie uma função recursiva que verifique se um elemento esta presente em uma lista, deixe explicita a assinatura da função

*Solução*:
<!-- name: 2-a -->
```haskell
elem' :: Eq a => a -> [a] -> Bool
elem' e (x:xs) = (e == x) || (elem' e xs)
elem' _ [] = False
```
<!-- require: 2-a
```haskell
main = do
    print $ True == (1 `elem'` [1,2,3])
    print $ True == (1 `elem'` [1,2])
    print $ False == (3 `elem'` [1])
    print $ False == (3 `elem'` [])
    print $ True == ('a' `elem'` "banana")
    print $ False == ('c' `elem'` "banana")
```
-->


### b) Crie um função que receba 3 valores numéricos, de qualquer tipo, e considerando que cada valor é a medida de um lado de um triângulo, retorne um valor do tipo Bool informando se estas são medidas validas para formar um triângulo.

*Solução*:
<!-- name: 2-b -->
```haskell
ehTriangulo :: (Num a, Ord a) => a -> a -> a -> Bool
ehTriangulo a b c = (a+b > c) && (a+c > b) && (b+c > a)
```

<!-- require: 2-b
```haskell
main = do
    print $ ehTriangulo 7 5 10
    print $ not $ ehTriangulo 7 5 100
```
-->


### c) Crie uma função recursiva que tenha dois parâmetros númericos, de qualquer tipo, e calcule a potenciação, o primeiro parâmetro sendo a base e o segundo o expoente.

*Solução*:
<!-- name: 2-c -->
```haskell
potencia :: (Fractional a, Ord a) => a -> a -> a
potencia _ 0 = 1
potencia b e
    | e > 0 = (potencia b (e-1)) * b
    | e < 0 = (potencia b (e+1)) / b
```
<!-- require: 2-c
```haskell
main = do
    print $ 4 == (potencia 2 2)
    print $ 8 == (potencia 2 3)
    print $ 1 == (potencia 2 0)
    print $ 1 == (potencia 2 0)
    print $ 2 == (potencia 0.5 (-1))
    print $ 2 == (potencia 0.5 (-1))
    print $ 0.25 == (potencia 2 (-2))
```
-->

## 3. Siga as instruções abaixo na sequência

### a) Crie um tipo Cor que possua um _value constructor_ de mesmo nome que carregue 3 valores do tipo Int.

*Solução*:
<!-- name: 3-a -->
```haskell
data Cor a = Cor a a a
```

### b) Cada um dos valores do tipo Int são relativos aos valores RGB (red, green, blue), pra cada um desses valores crie (manualmente) uma função de projeção, o nome das funções devem ser red, green e blue, respectvamente para cada um dos valores do tipo Int. 

*Solução*:
<!-- name: 3-b require: 3-a -->
```haskell
red :: Cor a -> a
red (Cor r _ _) = r

green :: Cor a -> a
green (Cor _ g _) = g

blue :: Cor a -> a
blue (Cor _ _ b) = b
```

### c) Ao invés de criar as funções de projeção manualmente, crie o tipo Cor utilizando record syntax

*Solução*:
<!-- name: 3-c -->
```haskell
data Cor a = Cor { red::a, green::a, blue::a }
```

### d) Crie uma função com o nome somaCor, que combine dois valores do tipo Cor, de forma que o resultado deve ser um novo valor, também do tipo Cor, onde os valores relativos ao RGB (red, green e blue), são relativos a soma dos valores RGB dos parâmetros da função, respectivamente. Caso algum valor relativo relativo ao valores RGB do resultado seja maior 

*Solução*:
<!-- name: 3-d require: 3-c -->
```haskell
somaCor :: (Ord a, Num a) => Cor a -> Cor a -> Cor a
somaCor a b = 
        Cor (canal red) (canal green) (canal blue)
    where
        canal f = min 255 $ (f a)+(f b)
```

### e) Crie um operador <+> que faça a mesma coisa que a função somaCor, utilize-se do conceito de currying para definir o operador. (Os símbolos de maior e menor fazem parte do operador)

*Solução*:
<!-- name: 3-e require: 3-d -->
```haskell
(<+>) :: (Ord a, Num a) => Cor a -> Cor a -> Cor a
(<+>) = somaCor
```

### f) Crie uma instância de Monoid para o tipo Cor, onde a operação bínaria seja o operador <+> e o elemento nêutro seja um valor do tipo Cor que contem os valores RGB como 0.

*Solução*:
<!-- name: 3-f require: 3-e -->
```haskell
instance (Ord a, Num a) => Semigroup (Cor a) where
    (<>) = (<+>)

instance (Ord a, Num a) => Monoid (Cor a) where
    mempty = Cor 0 0 0
```

## 4) Siga as intruções abaixo em sequência:

### a) Crie um tipo Cofre que possua uma type variable, e um value constructor de mesmo nome que o tipo, que carregue um valor que seja um lista do tipo da type variable.

*Solução*:
<!-- name: 4-a -->
```haskell
data Cofre a = Cofre [a]
```

### b) Crie uma instância do typeclass Functor para esse tipo.

*Solução*:
<!-- name: 4-b require: 4-a -->
```haskell
instance Functor Cofre where
    fmap f (Cofre x) = Cofre $ fmap f x
```

### c) Crie uma instância do typeclass Applicative para esse tipo.

*Solução*:
<!-- name: 4-c require: 4-b -->
```haskell
instance Applicative Cofre where
    pure x = Cofre [x]
    (Cofre f) <*> (Cofre x) = Cofre $ f <*> x
```

A  => pdf.nix +13 -0
@@ 1,13 @@
{ stdenv, pandoc, texlive }: stdenv.mkDerivation {
  pname = "notas-verao-pfpa";
  version = "1.0";
  src = ./.;
  buildInputs = [ pandoc texlive.combined.scheme-small ];
  buildPhase = ''
    pandoc lista.md -o lista.pdf
  '';
  installPhase = ''
    mkdir -p $out
    cp lista.pdf $out
  '';
}