Предложение Haskell do с несколькими типами монад

Я использую графическую библиотеку в Haskell под названиемТрехгрошовая-GUI, В этой библиотеке основная функция возвращаетUI монадный объект. Это вызывает у меня сильную головную боль, как при попытке распаковатьIO значения в локальные переменные я получаю сообщения об ошибках различных типов монад.

Вот пример моей проблемы. Это слегка измененная версия стандартной основной функции, как показано в примере кода Threepenny-GUI:

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))

Обратите внимание на пятую строку:

labelsAndValues <- shuffle [1..10]

Который возвращает следующую ошибку:

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]

Что касается моего вопроса, как мне распаковатьIO функция с использованием стандартной стрелки обозначения (<-), и продолжайте иметь эти переменные какIO () скорее, чемUI ()так что я могу легко передать их другим функциям.

В настоящее время единственным решением, которое я нашел, было использованиеliftIO, но это вызывает преобразование вUI тип монады, в то время как я на самом деле хочу продолжать использоватьIO тип.

Ответы на вопрос(3)

Ваш ответ на вопрос