1. O documento descreve um mini-curso sobre Haskell realizado em 2013, apresentando tópicos como OpenGL, tipos qualificados, classes, functores e monads.
2. É apresentado o básico de OpenGL para desenho gráfico em Haskell, assim como exemplos de inicialização e renderização.
3. Conceitos como tipos qualificados, classes e instâncias em Haskell são explicados, com ênfase em Eq, Ord, Drawable e conversões para OpenGL.
1. Mini-Curso
de Haskell -
SEMAC
2013/1
M. Millani
Básico de
OpenGl
Qualied
Types
Denindo
Classes
Algumas
Classes Úteis
Functor e
Monad
Handles
Referências
Mini-Curso de Haskell - SEMAC 2013/1
Marcelo Garlet Millani
Universidade Federal do Rio Grande do Sul
Instituto de Informática
Grupo PET Computação
22 de maio de 2013
2. Mini-Curso
de Haskell -
SEMAC
2013/1
M. Millani
Básico de
OpenGl
Qualied
Types
Denindo
Classes
Algumas
Classes Úteis
Functor e
Monad
Handles
Referências
1 Básico de OpenGl
2 Qualied Types
Denindo Classes
Algumas Classes Úteis
3 Functor e Monad
4 Handles
5 Referências
3. Mini-Curso
de Haskell -
SEMAC
2013/1
M. Millani
Básico de
OpenGl
Qualied
Types
Denindo
Classes
Algumas
Classes Úteis
Functor e
Monad
Handles
Referências
OpenGL
• OpenGl é uma biblioteca gráca
• Permite aproveitar a GPU para desenhos
• Capaz de trabalhar em 3D, mas usaremos apenas 2D
• GHC possui bindings para Haskell
• Módulo Graphics.Rendering.OpenGL
• Pacote libghc-opengl-dev no Linux (Debian)
• Usaremos a GLUT (Graphics.UI.GLUT) para a janela
• Pacote libghc-glut-dev no Linux (Debian)
4. Mini-Curso
de Haskell -
SEMAC
2013/1
M. Millani
Básico de
OpenGl
Qualied
Types
Denindo
Classes
Algumas
Classes Úteis
Functor e
Monad
Handles
Referências
Inicialização
getArgsAndInitialize Inicializa a GLUT
createWindow Cria uma janela gráca
displayCallback Determina a função que será usada para
desenhar
mainLoop Inicia o processo de desenho
Exemplo
1 main = do
2 g e t A r g s A n d I n i t i a l i z e
3 createWindow Hello World
4 d i s p l a y C a l l b a c k $= d i s p l a y myPoints
5 mainLoop
5. Mini-Curso
de Haskell -
SEMAC
2013/1
M. Millani
Básico de
OpenGl
Qualied
Types
Denindo
Classes
Algumas
Classes Úteis
Functor e
Monad
Handles
Referências
Desenho
clear Limpa um buer
renderPrimitive Desenha uma primitiva do OpenGL
ush Finaliza o desenho
vertex Especica um vértice do polígono que está sendo
desenhado
Exemplo
1 d i s p l a y p = do
2 c l e a r [ ColorBuffer ]
3 r e n d e r P r i m i t i v e LineLoop $ do
4 mapM_ (( x , y , z)−vertex$Vertex3 x y z ) p
5 f l u s h
6. Mini-Curso
de Haskell -
SEMAC
2013/1
M. Millani
Básico de
OpenGl
Qualied
Types
Denindo
Classes
Algumas
Classes Úteis
Functor e
Monad
Handles
Referências
Exercício
Exercício
Faça um programa que desenhe o triângulo de Sierpinski.
• Composto por triângulos retângulos isósceles
• Divide-se em três regiões: direita, cima e centro
• Cada região será composta por um triângulo com a metade
do lado
7. Mini-Curso
de Haskell -
SEMAC
2013/1
M. Millani
Básico de
OpenGl
Qualied
Types
Denindo
Classes
Algumas
Classes Úteis
Functor e
Monad
Handles
Referências
1 Básico de OpenGl
2 Qualied Types
Denindo Classes
Algumas Classes Úteis
3 Functor e Monad
4 Handles
5 Referências
8. Mini-Curso
de Haskell -
SEMAC
2013/1
M. Millani
Básico de
OpenGl
Qualied
Types
Denindo
Classes
Algumas
Classes Úteis
Functor e
Monad
Handles
Referências
Para que servem
• Uso de funções polimórcas
• Restringem os tipos para os quais a função está denida
Exemplo
Função de soma:
1 (+) : : Num a= a−a−a
Denida para qualquer a tal que a seja um membro de Num.
9. Mini-Curso
de Haskell -
SEMAC
2013/1
M. Millani
Básico de
OpenGl
Qualied
Types
Denindo
Classes
Algumas
Classes Úteis
Functor e
Monad
Handles
Referências
Como usar
• Denimos como as funções da classe serão aplicadas para
um certo tipo de dado
• Em alguns casos, não é necessário denir todas as funções
• Por exemplo, basta denir igualdade (==) para se ter
diferença (/=)
Exemplo
1 instance Eq a = Eq ( Figure a ) where
2 C i r c l e r == C i r c l e s =
3 r == s
4 Rectangle w h == Rectangle a b =
5 w == a h == b
6 _ == _ = False
10. Mini-Curso
de Haskell -
SEMAC
2013/1
M. Millani
Básico de
OpenGl
Qualied
Types
Denindo
Classes
Algumas
Classes Úteis
Functor e
Monad
Handles
Referências
Derivação
• Algumas classes possuem suporte para derivação
• Usam uma implementação padrão para qualquer tipo de
dado
• Funciona somente com:
• Eq
• Ord
• Enum
• Bounded
• Show
• Read
11. Mini-Curso
de Haskell -
SEMAC
2013/1
M. Millani
Básico de
OpenGl
Qualied
Types
Denindo
Classes
Algumas
Classes Úteis
Functor e
Monad
Handles
Referências
Derivação
Exemplo
1 data Quadrilatero a = Retangulo a a | Quadrado a
2 deriving (Show, Read,Eq, Ord)
12. Mini-Curso
de Haskell -
SEMAC
2013/1
M. Millani
Básico de
OpenGl
Qualied
Types
Denindo
Classes
Algumas
Classes Úteis
Functor e
Monad
Handles
Referências
Denindo Classes
• Faremos uma classe para uniformizar o desenho de
primitivas
• Minimizaremos a inuência do OpenGL
• Ter os vértices é o suciente para desenhar algo
Funções
1 class Drawable d where
2 toVertex : : d − ( Float , Float) −
3 [ ( Float , Float ) ]
4 draw : : PrimitiveMode − d −
5 ( Float , Float) − IO ()
6 drawWire : : ( Float , Float) −
7 d − IO ()
13. Mini-Curso
de Haskell -
SEMAC
2013/1
M. Millani
Básico de
OpenGl
Qualied
Types
Denindo
Classes
Algumas
Classes Úteis
Functor e
Monad
Handles
Referências
Conversões
• OpenGL usa o tipo GLoat
• Usaremos uma função para converter de Float para GLoat
• Essa função pode car fora da classe
Conversões
1 convertToGLfloat x = ( realToFrac x ) : : GLfloat
2 convertPoint (x , y ) =
3 vertex $ Vertex2 ( convertToGLfloat x )
4 ( convertToGLfloat y )
14. Mini-Curso
de Haskell -
SEMAC
2013/1
M. Millani
Básico de
OpenGl
Qualied
Types
Denindo
Classes
Algumas
Classes Úteis
Functor e
Monad
Handles
Referências
Implementação
• Providenciaremos uma implementação padrão para draw e
drawWire
• Basta fornecer uma implementação para toVertex
Funções
1 draw mode f i g u r e point =
2 r e n d e r P r i m i t i v e mode $
3 mapM_ convertPoint ( toVertex f i g u r e point )
4
5 drawWire point f i g u r e =
6 draw LineLoop f i g u r e point
15. Mini-Curso
de Haskell -
SEMAC
2013/1
M. Millani
Básico de
OpenGl
Qualied
Types
Denindo
Classes
Algumas
Classes Úteis
Functor e
Monad
Handles
Referências
Exercício
Exercício
Faça com que o tipo Figure seja um membro da classe
Drawable. Com isso, desenhe um fractal que seja um círculo
dentro de um quadrado dentro de um círculo dentro de um
quadrado ...
16. Mini-Curso
de Haskell -
SEMAC
2013/1
M. Millani
Básico de
OpenGl
Qualied
Types
Denindo
Classes
Algumas
Classes Úteis
Functor e
Monad
Handles
Referências
Eq
Denição
1 class Eq a where
2 (==), (/=) : : a − a − Bool
3
4 x /= y = not ( x == y )
5 x == y = not ( x /= y )
17. Mini-Curso
de Haskell -
SEMAC
2013/1
M. Millani
Básico de
OpenGl
Qualied
Types
Denindo
Classes
Algumas
Classes Úteis
Functor e
Monad
Handles
Referências
Ord
Denição
1 class (Eq a ) = Ord a where
2 compare : : a − a − Ordering
3 ( ) , (=), (=), () : : a − a − Bool
4 max, min : : a − a − a
5
6 compare x y | x == y = EQ
7 | x = y = LT
8 | otherwise = GT
18. Mini-Curso
de Haskell -
SEMAC
2013/1
M. Millani
Básico de
OpenGl
Qualied
Types
Denindo
Classes
Algumas
Classes Úteis
Functor e
Monad
Handles
Referências
Ord (Continuação)
Denição
1 −− c l a s s ( Eq a ) = Ord a where
2 x = y = compare x y /= GT
3 x y = compare x y == LT
4 x = y = compare x y /= LT
5 x y = compare x y == GT
19. Mini-Curso
de Haskell -
SEMAC
2013/1
M. Millani
Básico de
OpenGl
Qualied
Types
Denindo
Classes
Algumas
Classes Úteis
Functor e
Monad
Handles
Referências
Ord (Continuação)
Denição
1 −− c l a s s ( Eq a ) = Ord a where
2 max x y | x = y = y
3 | otherwise = x
4 min x y | x = y = x
5 | otherwise = y
20. Mini-Curso
de Haskell -
SEMAC
2013/1
M. Millani
Básico de
OpenGl
Qualied
Types
Denindo
Classes
Algumas
Classes Úteis
Functor e
Monad
Handles
Referências
Exercício
Exercício
Estenda a denição de Figure para que ela faça parte da classe
Ord. Use a área de gura como critério.
• Para testar a sua denição, use a função sort e sortBy da
biblioteca Data.List
• sort :: Ord a = [a] - [a]
• sortBy :: (a - a - Ordering) - [a] - [a]
21. Mini-Curso
de Haskell -
SEMAC
2013/1
M. Millani
Básico de
OpenGl
Qualied
Types
Denindo
Classes
Algumas
Classes Úteis
Functor e
Monad
Handles
Referências
1 Básico de OpenGl
2 Qualied Types
Denindo Classes
Algumas Classes Úteis
3 Functor e Monad
4 Handles
5 Referências
22. Mini-Curso
de Haskell -
SEMAC
2013/1
M. Millani
Básico de
OpenGl
Qualied
Types
Denindo
Classes
Algumas
Classes Úteis
Functor e
Monad
Handles
Referências
Functor
• Dene um meio de transformar tipos de dados
Classe
1 class Functor f where
2 fmap : : ( a − b) − f a − f b
• f é um construtor
Propriedades Esperadas
1 fmap id = id
2 fmap ( f . g) = fmap f . fmap g
23. Mini-Curso
de Haskell -
SEMAC
2013/1
M. Millani
Básico de
OpenGl
Qualied
Types
Denindo
Classes
Algumas
Classes Úteis
Functor e
Monad
Handles
Referências
Exemplo
Exemplo
1 instance Functor [ ] where
2 fmap f [ ] = [ ]
3 fmap f (h : t l ) = f h : fmap f t l
• Comportamento igual ao da função map
24. Mini-Curso
de Haskell -
SEMAC
2013/1
M. Millani
Básico de
OpenGl
Qualied
Types
Denindo
Classes
Algumas
Classes Úteis
Functor e
Monad
Handles
Referências
Monad
Denição
1 class Monad m where
2 (=) : : m a − ( a − m b) − m b −− b i n d
3 () : : m a − m b − m b −− s e q u e n c e
4 return : : a − m a
5 fail : : String − m a
6
7 m k = m = _ − k
8 fail s = error s
25. Mini-Curso
de Haskell -
SEMAC
2013/1
M. Millani
Básico de
OpenGl
Qualied
Types
Denindo
Classes
Algumas
Classes Úteis
Functor e
Monad
Handles
Referências
Sintaxe do
• Apenas açúcar sintático
• Na realidade, utiliza os operadores de mônadas
Regras
1 do e
2 − e
3 do e1 ; e2 ; . . . ; en
4 − e1 do e2 ; . . . ; e_n
26. Mini-Curso
de Haskell -
SEMAC
2013/1
M. Millani
Básico de
OpenGl
Qualied
Types
Denindo
Classes
Algumas
Classes Úteis
Functor e
Monad
Handles
Referências
Monad
Regras
1 do pat − e1 ; e2 ; . . . ; en
2 −
3 let ok pat = do e2 ; . . . ; en
4 ok _ = fail . . .
5 in e1 = ok
27. Mini-Curso
de Haskell -
SEMAC
2013/1
M. Millani
Básico de
OpenGl
Qualied
Types
Denindo
Classes
Algumas
Classes Úteis
Functor e
Monad
Handles
Referências
Monad
Regras
1 do let d e c l l i s t ; e2 ; . . . ; en
2 − let d e c l l i s t in do e2 ; . . . ; en
28. Mini-Curso
de Haskell -
SEMAC
2013/1
M. Millani
Básico de
OpenGl
Qualied
Types
Denindo
Classes
Algumas
Classes Úteis
Functor e
Monad
Handles
Referências
1 Básico de OpenGl
2 Qualied Types
Denindo Classes
Algumas Classes Úteis
3 Functor e Monad
4 Handles
5 Referências
29. Mini-Curso
de Haskell -
SEMAC
2013/1
M. Millani
Básico de
OpenGl
Qualied
Types
Denindo
Classes
Algumas
Classes Úteis
Functor e
Monad
Handles
Referências
Handles
• Usados para abrir um arquivo para diversas modicações
• São mais ecientes do que funções como readFile ou
writeFile
• É necessário lembrar de fechar o arquivo
• Usa-se a biblioteca System.IO
Algumas Funções
1 openFile : : FilePath − IOMode − IO Handle
2 hClose : : Handle − IO ()
3 hPutStr : : Handle − String − IO ()
4 hGetChar : : Handle − IO Char
5 hGetLine : : Handle − IO String
6 hGetContents : : Handle − IO String
30. Mini-Curso
de Haskell -
SEMAC
2013/1
M. Millani
Básico de
OpenGl
Qualied
Types
Denindo
Classes
Algumas
Classes Úteis
Functor e
Monad
Handles
Referências
Exercício
Exercício
Faça um programa que escreva diversas guras geométricas em
um arquivo (usando a classe Show) e depois leia essas guras
do arquivo (usando Read). Trate o arquivo com handles. Derive
as classes em vez de implementá-las.
• hGetContents é uma função de leitura lazy
• Para conveniência, fechem o arquivo de leitura no nal do
programa, em vez de no nal da leitura.
• Existem alternativas melhores, como tratar o nal do
arquivo
31. Mini-Curso
de Haskell -
SEMAC
2013/1
M. Millani
Básico de
OpenGl
Qualied
Types
Denindo
Classes
Algumas
Classes Úteis
Functor e
Monad
Handles
Referências
Referências
Hal Daumé III, Yet Another Haskell Tutorial
Hudak, Paul. The Haskell School of Expression
http:
//www.haskell.org/haskellwiki/OpenGLTutorial1
http://www.haskell.org/onlinereport