I'm using a graphic library in Haskell called ThreePennyUI. In this library the main function returns a UI monad object. This causes me much headache as when I attempt to unpack IO values into local variables I receive errors complaining of different monad types.
Here's an example of my problem: This is a slightly modified version of the standard main function, as given by ThreePennyUI's code example:
main :: IO () main = startGUI defaultConfig setup setup :: Window -> UI () setup w = do labelsAndValues <- shuffle [1..10] shuffle :: [Int] -> IO [Int] shuffle  = return  shuffle xs = do randomPosition <- getStdRandom (randomR (0, length xs - 1)) let (left, (a:right)) = splitAt randomPosition xs fmap (a:) (shuffle (left ++ right))
Please notice the fifth line -
labelsAndValues <- shuffle [1..10]
Which returns the following error:
Couldn't match type ‘IO’ with ‘UI’ Expected type: UI [Int] Actual type: IO [Int] In a stmt of a 'do' block: labelsAndValues <- shuffle [1 .. 10]
As to my question, how do I unpack the IO function using the standard arrow notation ( <- ), and keep on having these variables as IO () rather than UI (), so I can easily pass them on to other functions.
Currently, the only solution I found was to use liftIO, but this causes conversion to a the UI monad type, while I actually want to keep on using the IO type.