I am very new to Haskell and do not have good understanding of monads for now. I am using gloss for making chess. The issue I am facing is in the loading of multiple images. I am using loadBMP function provided by haskell to load image. Its signature is:
loadBMP :: FilePath -> IO Picture
I can load single image but can't load array of images.
-- This function calculates the path of all the images and then apply loadBMP function on it.
loadPieceImages :: [IO Picture]
loadPieceImages = do
map (loadBMP . (\n -> "images/" ++ n ++ ".bmp") . (\n -> if n < 6 then show n ++ "-w" else show (n `mod` 6) ++ "-b")) [0 .. 12]
main :: IO ()
main = do
images <- loadPieceImages -- On this line I am getting error.
play window (makeColor 1 0 0 1) 30 initialState draw transform (const id)
The main issue is that I have [IO Picture] type but I don't how will be turn it into [Picture].
This thing might be very basic but I can't understand monads for now. So kindly explain the answer you give.
Since you've (correctly) declared
mainasIO (), thedonotation and the<-arrow enables you to 'peel off' theIOwrapper. Thus, when you writeimages <- loadPieceImages, the compiler expectsloadPieceImagesto have anIOtype.loadPieceImages, however, has the type[IO Picture], which is why the compiler complains. The outermost wrapper is[], notIO.If, on the other hand, you had a
IO [Picture]value, you'd be able to use the<-arrow to peel of theIOwrapper to 'get at' the[Picture]list inside it.In other words, you need a function with the type
[IO Picture] -> IO [Picture]. You can Hoogle that type and consider the suggestions.Once you get the hang of it, you'll start to notice that whenever you want to 'flip' the 'stacking' of two wrappers (like
IOand[]), there's a general-purpose function for that: sequence. This function takes a list of anyMonad mand flips it tom [a]. SinceIOis aMonadinstance, that'll work here as well.So, something like
should work (I haven't actually tried to compile this, since the OP isn't a minimal reproducible example, so it's possible you'll have to tweak this a bit, but that's the general idea: use
sequence).