Я учусь Haskell, прыгнув прямо в OpenGL, и я не могу расшифровать этот код:Как работает этот код OpenGL Haskell?
display :: DisplayCallback
display = do
let color3f r g b = color $ Color3 r g (b :: GLfloat)
vertex3f x y z = vertex $ Vertex3 x y (z :: GLfloat)
clear [ColorBuffer]
renderPrimitive Quads $ do
color3f 1 0 0
vertex3f 0 0 0
vertex3f 0 0.2 0
vertex3f 0.2 0.2 0
vertex3f 0.2 0 0
color3f 0 1 0
vertex3f 0 0 0
vertex3f 0 (-0.2) 0
vertex3f 0.2 (-0.2) 0
vertex3f 0.2 0 0
color3f 0 0 1
vertex3f 0 0 0
vertex3f 0 (-0.2) 0
vertex3f (-0.2) (-0.2) 0
vertex3f (-0.2) 0 0
color3f 1 0 1
vertex3f 0 0 0
vertex3f 0 0.2 0
vertex3f (-0.2) 0.2 0
vertex3f (-0.2) 0 0
flush
Мое понимание до сих пор:
display
является функцией. ВОПРОС: Что такое DisplayCallback?do
указывает цепочки вычислений, что-то делать с IO монадcolor3f
иvertex3f
локальные функции с тремя аргументами, определенные вdo
используяlet
ключевое слово- я предполагаю, что
color
иvertex
является функцией OPENGL обертка дляglColor*
иglVertex*
.
Теперь это, где это становится запутанным:
Color3
иVertex3
, кажется, какая-то структура данных, состоящая из трех аргументов. ВОПРОС: Зачем нужна структура данных здесь? Почему дизайнеры API решили использовать его здесь?color3f
Функциональные вызовыcolor
Функция и передает в одном аргументе - структура данныхColor3
с данными r g b. По какой-то причине тип данных здесь указан только для последнего аргумента(b :: GLfloat)
ВОПРОС: Почему тип данных указан только для последнего аргумента, почему он указан здесь вообще?ВОПРОС: Почему знак доллара используется при вызове функции
color
color $ Color3 r g (b :: GLfloat)
?
Продолжая:
clear
является оболочкой для OpenGLglClear
и принимает в качестве аргумента список, в данном случае, содержащий только один элемент[ColorBuffer]
.renderPrimitive
, как представляется, является оберточной функцией для openglglBegin
,Quads
, по-видимому, является типом данных. ВОПРОС: Что будет дальше? Что указывает$ do
? (серия вычислений? что-то, что-то IO monads?).flush
является оберткой дляglFlush
.
(Обучение с использованием привязки к большой внешней библиотеке может исказить вашу картину Haskell, так как ваш опыт будет искажен решениями, принятыми (а) решениями, включая выбор языка, авторов OpenGL и (б) решения, в том числе обязательные для функционального перевода, авторов Haskell-связывания. В частности, эти огромные блоки монадического запаха кода императива, и я бы пошел на некоторые длины при написании кода Haskell, чтобы этого избежать. К сожалению, некоторые внешние библиотеки как правило, толкают вас в этом унииоматическом направлении.) – AndrewC
Я прыгнул прямо с OpenGL (с которым я знаком), потому что компьютерная графика и gamedev - это именно то, что я собираюсь использовать для Haskell. По возможности я постараюсь придерживаться идиоматического Haskell и чистого функционального программирования. – JBeurer