I'm creating a game with Gloss. I have this function :
block :: IO (Maybe Picture)
block = loadJuicyPNG "block.png"
How do I take this IO (Maybe Picture) and turn it into a Picture?
I'm creating a game with Gloss. I have this function :
block :: IO (Maybe Picture)
block = loadJuicyPNG "block.png"
How do I take this IO (Maybe Picture) and turn it into a Picture?
This is basically the same answer as Bartek's, but using a different approach.
Let's say you have a function foo :: Picture -> Picture
the transforms a picture in some way. It expects a Picture
as an argument, but all you have is block :: IO (Maybe Picture)
; there may or may not be a picture buried in there, but it's all you have.
To start, let's assume you have some function foo' :: Maybe Picture -> Maybe Picture
. It's definition is simple:
foo' :: Maybe Picture -> Maybe Picture
foo' = fmap foo
So simple, in fact, that you never actually write it; wherever you would use foo'
, you just use fmap foo
directly. What this function does, you will recall, is return Nothing
if it gets Nothing
, and return Just (foo x)
if it gets some value Just x
.
Now, given that you have foo'
, how do you apply it to the value buried in the IO
type? For that, we'll use the Monad
instanced for IO
, which provides us with two functions (types here specialized to IO
):
return :: a -> IO a
(>>=) :: IO a -> (a -> IO b) -> IO b
In our case, we recognize that both a
and b
are Maybe Picture
. If foo' :: Maybe Picture -> Maybe Picture
, then return . foo' :: Maybe Picture -> IO (Maybe Picture)
. That means we can finally "apply" foo
to our picture:
> :t block >>= return . (fmap foo)
block >>= return . (fmap foo) :: IO (Maybe Picture)
But we aren't really applying foo
ourselves. What we are really doing is lifting foo
into a context where, once block
is executed, foo'
can be called on whatever block
produces.
You need to bind the value. This is done either with the bind function
(>>=)
, or bydo
-notation:It is a
Maybe Picture
because the loading might fail, and you have to handle that possible failure somehow.