Funções e Paradigma Funcional com Haskell - Parte 1

Funções e Paradigma Funcional com Haskell - Parte 1
Photo by Nicolás Flor / Unsplash

Haskell é uma linguagem de programação puramente funcional, conhecida por sua abstração e eficiência. Surgiu em 1990 como um padrão para linguagens funcionais. Diferente do paradigma imperativo, onde você escreve código que descreve em detalhes como fazer algo, Haskell se concentra em o que fazer, descrevendo as relações entre dados.

O paradigma funcional se baseia em funções matemáticas. Em Haskell, funções são consideradas cidadãs de primeira classe. Isso significa que podem ser passadas como parâmetros, retornadas por outras funções e atribuídas a variáveis.

Configuração do Ambiente de Desenvolvimento

Para começar com Haskell:

  1. Instale o GHC (Glasgow Haskell Compiler): O GHC é o compilador mais usado para Haskell. Visite haskell.org/downloads para instruções de instalação.
  2. Crie um novo projeto com Cabal: Cabal é um sistema de build e gerenciador de pacotes. Use cabal init para iniciar um novo projeto.

Test-Driven Development (TDD) em Haskell

TDD é uma técnica de desenvolvimento de software onde você escreve testes antes do código de produção. Isso ajuda a definir os objetivos do seu código antes de implementá-los.

Escrevendo Testes Primeiro

Com Haskell, você pode usar frameworks como HUnit para testes unitários ou QuickCheck para testes baseados em propriedades.

-- Exemplo de teste com HUnit
testList = TestList [TestCase (assertEqual "Testa se 2 + 2 é 4" 4 (2 + 2))]

Desenvolvimento Orientado a Testes

Agora, escreva uma função que passe neste teste. O objetivo é fazer o teste passar da maneira mais simples possível.

Explorando a Sintaxe de Haskell

Haskell tem uma sintaxe única e elegante.

Tipos e Funções Básicas

Tudo em Haskell tem um tipo. Os tipos ajudam a tornar o código mais seguro e compreensível.

soma :: Int -> Int -> Int
soma x y = x + y

Funções de Alta Ordem e Recursão

Haskell brilha com funções de alta ordem e uso de recursão.

-- Função de alta ordem
aplicarDuasVezes :: (a -> a) -> a -> a
aplicarDuasVezes f x = f (f x)

-- Recursão
fatorial :: Int -> Int
fatorial 0 = 1
fatorial n = n * fatorial (n - 1)

Exemplo Prático: Filtrando uma Lista

Vamos criar uma função que filtra elementos de uma lista que satisfazem uma determinada condição.

-- Teste
testFiltro = TestCase (assertEqual "Filtra números maiores que 5" [6,7,8] (filtro (>5) [1,2,6,7,8]))

-- Função
filtro :: (a -> Bool) -> [a] -> [a]
filtro _ [] = []
filtro p (x:xs)
   | p x       = x : filtro p xs
   | otherwise = filtro p xs

Desenvolvendo uma Função de Soma com TDD em Haskell

Passo 1: Configurar o Ambiente

Antes de começar, certifique-se de que você tem o Stack, uma ferramenta de desenvolvimento Haskell, instalada em seu sistema.

Passo 2: Criar um Novo Projeto

Abra um terminal e crie um novo projeto Stack:

stack new sumProject
cd sumProject

Isso cria uma nova pasta chamada sumProject com uma estrutura de projeto básica.

Passo 3: Adicionar Dependências de Teste

Edite o arquivo package.yaml e adicione hspec na seção de dependências de teste:

tests:
  sumProject-test:
    main:                Spec.hs
    source-dirs:         test
    dependencies:
      - sumProject
      - hspec

Passo 4: Escrever um Teste

Antes de implementar a função de soma, vamos escrever um teste para ela. Crie um arquivo de teste em test/Spec.hs:

import Test.Hspec
import Lib

main :: IO ()
main = hspec $ do
  describe "sumFunction" $ do
    it "correctly sums two numbers" $ do
      sumFunction 5 3 `shouldBe` 8

Este teste verifica se a função sumFunction retorna a soma correta de dois números.

Passo 5: Implementar a Função

Agora, implemente a função sumFunction no arquivo src/Lib.hs:

module Lib
    ( sumFunction
    ) where

sumFunction :: Int -> Int -> Int
sumFunction x y = x + y

Passo 6: Executar o Teste

Volte ao terminal e execute o teste:

stack test

Se tudo estiver correto, o teste passará, indicando que a função sumFunction está funcionando conforme esperado.

Read more