Desenvolvendo uma Biblioteca JSON em Haskell¶
Neste capítulo, iniciamos o projeto central da Unidade 2: uma biblioteca completa para manipulação e serialização de dados em formato JSON (JavaScript Object Notation), adaptando o clássico Real World Haskell (Capítulo 5) para um projeto moderno gerenciado pelo Stack.
Tutorial completo no blog
O passo a passo detalhado — do stack new até o pacote final, com todos os módulos, códigos e explicações — está publicado como tutorial no blog do LambdaGEO:
Construindo e Testando uma Biblioteca Haskell: JSON, Pretty Printing e QuickCheck
Este capítulo apresenta os conceitos e as decisões de projeto; siga a Parte 1 do tutorial para construir a biblioteca.
Leitura complementar
O capítulo original que inspirou este projeto: Real World Haskell, Cap. 5 — Writing a library: working with JSON data (em inglês; o tutorial do blog moderniza o código para GHC 9.x e Stack).
📜 Um Tour Relâmpago pelo JSON¶
O JSON é uma representação pequena e simples para armazenar e transmitir dados estruturados — por exemplo, de um serviço web para uma aplicação no navegador. O formato é descrito em www.json.org e na RFC 4627. Ele suporta quatro tipos básicos de valor:
E dois tipos compostos: o array, uma sequência ordenada de valores, e o objeto, uma coleção não ordenada de pares nome/valor (os nomes são sempre strings):
🧩 A Ideia Central: Modelar o Domínio com um ADT¶
A essência da biblioteca é a correspondência direta entre a gramática do JSON e um tipo algébrico: cada tipo do JSON vira um construtor de valor:
data JValue = JString String
| JNumber Double
| JBool Bool
| JNull
| JObject [(String, JValue)]
| JArray [JValue]
deriving (Eq, Ord, Show)
Note que JObject e JArray são recursivos — carregam outros JValue — exatamente como no capítulo de tipos recursivos. Com o tipo definido, todo o restante da biblioteca é pattern matching sobre ele: accessors seguros que retornam Maybe (getString, getInt, ...) e funções de renderização.
🏗️ As Decisões de Projeto¶
O tutorial constrói a biblioteca em três módulos, e cada um materializa uma lição de engenharia funcional:
SimpleJSON.hs— o ADTJValuee os accessors. Lição: modelagem de domínio com tipos e extração segura viaMaybe.Prettify.hs— uma biblioteca genérica de pretty printing baseada em um tipo abstratoDoc. Lição: renderizar direto paraStringfunciona, mas amarra a implementação; ao basear a biblioteca em um tipo abstrato, podemos trocar a representação interna sem que os usuários percebam.PrettyJSON.hs— o renderizador que converteJValueemDoc, cuidando de escapes de strings e caracteres Unicode. Lição: separar a geração do formato da impressão em si — a renderização é uma função pura, e oIOfica só nas bordas do programa.
Além dos módulos, o tutorial cobre a estrutura do projeto Stack (biblioteca + executável), o sistema de exportações dos módulos e o empacotamento — conectando diretamente com o capítulo de projetos modernos com Stack.
🎯 O que Você Deve Dominar ao Final¶
- Definir um ADT recursivo que modela um formato de dados real;
- Escrever accessors totais usando
Maybe; - Explicar por que a biblioteca usa um tipo abstrato
Docem vez de renderizar direto paraString; - Organizar módulos com listas de exportação explícitas em um projeto Stack.
No próximo capítulo, garantiremos a correção da biblioteca com testes baseados em propriedades usando o QuickCheck — a Parte 2 do mesmo tutorial.