IO (возможно изображение) -> изображение - PullRequest
0 голосов
/ 07 декабря 2018

Я создаю игру с Блеском.У меня есть эта функция:

block :: IO (Maybe Picture)
block = loadJuicyPNG "block.png"

Как мне взять этот IO (возможно изображение) и превратить его в изображение?

Ответы [ 2 ]

0 голосов
/ 07 декабря 2018

Это в основном тот же ответ, что и у Бартека, но с использованием другого подхода.

Допустим, у вас есть функция foo :: Picture -> Picture, которая каким-то образом преобразует изображение.Он ожидает Picture в качестве аргумента, но все, что у вас есть, это block :: IO (Maybe Picture);там может быть или не быть картинка, скрытая там, но это все, что у вас есть.

Для начала давайте предположим, что у вас есть какая-то функция foo' :: Maybe Picture -> Maybe Picture.Его определение простое:

foo' :: Maybe Picture -> Maybe Picture
foo' = fmap foo

На самом деле настолько просто, что вы никогда его не напишите;где бы вы ни использовали foo', вы просто используете fmap foo напрямую.Как вы помните, эта функция возвращает Nothing, если получает Nothing, и возвращает Just (foo x), если получает некоторое значение Just x.

Теперь, учитывая, что у вас есть foo'как применить его к значению, скрытому в типе IO?Для этого мы будем использовать экземпляр Monad для IO, который предоставляет нам две функции (типы здесь специализируются на IO):

return :: a -> IO a
(>>=) :: IO a -> (a -> IO b) -> IO b

В нашем случае мы признаем, что обаa и b равны Maybe Picture.Если foo' :: Maybe Picture -> Maybe Picture, то return . foo' :: Maybe Picture -> IO (Maybe Picture).Это означает, что мы наконец можем «применить» foo к нашей картинке:

> :t block  >>= return . (fmap foo)
block  >>= return . (fmap foo) :: IO (Maybe Picture)

Но мы на самом деле не применяем foo сами.То, что мы действительно делаем, - это поднятие foo в контекст, где после выполнения block можно вызывать foo' для всего, что block производит.

0 голосов
/ 07 декабря 2018

Вам необходимо связать значение.Это делается либо с помощью функции связывания (>>=), либо с помощью do -обозначения:

main :: IO ()
main = do
    pic <- block
    case pic of
        Just p -> ...   -- loading succeeded, p is a Picture
        Nothing -> ...  -- loading failed

Это Maybe Picture, поскольку загрузка может завершиться неудачно, и вы должны как-то обработать этот возможный сбой..

...