52700.fb2 Учебник по Haskell - читать онлайн бесплатно полную версию книги . Страница 320

Учебник по Haskell - читать онлайн бесплатно полную версию книги . Страница 320

main = do

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