52700.fb2
var <- newIORef 2
x <- readIORef var
print x
writeIORef var 4
x <- readIORef var
print x
Эта запись выглядит как последовательность действий. Не правда ли очень похоже на обычный импера-
тивный язык. Такие переменные встречаются очень часто в библиотеках, заимствованных из~С.
StateVar
В модуле Data.StateVar определены типы, которые накладывают ограничение на права по чтению и
записи. Мы можем определять переменные доступные только для чтения (GettableStateVar a), только для
записи (SettableStateVar a) или обычные изменяемые переменные (SetVar a).
Операции чтения и записи описываются с помощью классов:
class HasGetter s where
get :: s a -> IO a
class HasSetter s where
($=) :: s a -> a -> IO ()
Основные библиотеки | 289
Тип IORef принадлежит и тому, и другому классу:
main = do
var <- newIORef 2
x
<- get var
print x
var $= 4
x
<- get var
print x
OpenGL
OpenGL является ярким примером библиотеки построенной на изменяемых переменных. OpenGL можно
представить как большой конечный автомат. Каждая строчка кода – это запрос на изменение состояния. При-
чём этот автомат является глобальной переменной. Его текущее состояние зависит от всей цепочки преды-
дущих команд. Параметры рисования задаются глобальными переменными (тип StateVar).
OpenGL не зависит от конкретной оконной системы, она отвечает лишь за рисование. Для того чтобы
создать окно и перехватывать в нём действия пользователя нам понадобится отдельная библиотека. Для
этого мы воспользуемся GLFW, это библиотека также пришла в Haskell из С. Интерфейсы GLFW и OpenGL очень
похожи. Мы будем обновлять различные параметры библиотеки с помощью типа StateVar. Давайте создадим
окно и закрасим фон белым цветом:
module Main where
import Graphics.UI.GLFW
import Graphics.Rendering.OpenGL
import System.Exit
title = ”Hello OpenGL”
width
= 700
height
= 600
main = do
initialize